Added library functions for setting and parsing cookies.
[jsvc.git] / src / dolda / jsvc / util / Params.java
CommitLineData
efa9722b
FT
1package dolda.jsvc.util;
2
3import dolda.jsvc.*;
4import java.util.*;
5import java.io.*;
6import java.net.*;
7import java.nio.charset.CharacterCodingException;
8
9public class Params {
141e5e3c 10 public static class EncodingException extends ClientError {
efa9722b 11 public EncodingException(String msg) {
141e5e3c 12 super("Invalid parameter encoding", msg);
efa9722b
FT
13 }
14 }
15
d7bc1a7a 16 public static MultiMap<String, String> urlparams(Reader in) throws IOException {
efa9722b
FT
17 try {
18 MultiMap<String, String> ret = new WrappedMultiMap<String, String>(new TreeMap<String, Collection<String>>());
19 String st = "key";
20 String key = null; /* Java is stupid. */
21 MixedBuffer buf = new MixedBuffer();
efa9722b 22 while(true) {
d7bc1a7a 23 int c = in.read();
efa9722b
FT
24 if(st == "key") {
25 if(c == '%') {
efa9722b 26 try {
d7bc1a7a
FT
27 int d1 = in.read();
28 int d2 = in.read();
29 buf.append((byte)((Misc.hex2int((char)d1) << 4) | Misc.hex2int((char)d2)));
efa9722b
FT
30 } catch(NumberFormatException e) {
31 throw(new EncodingException("Invalid character escape"));
32 }
efa9722b
FT
33 } else if(c == '=') {
34 key = buf.convert();
35 buf = new MixedBuffer();
36 st = "val";
37 } else if(c == '&') {
38 ret.add(buf.convert(), "");
39 buf = new MixedBuffer();
40 } else if(c == -1) {
41 if(buf.size() == 0) {
42 break;
43 } else {
44 ret.add(buf.convert(), "");
45 buf = new MixedBuffer();
46 }
47 } else {
48 buf.append((char)c);
49 }
50 } else if(st == "val") {
51 if(c == '%') {
efa9722b 52 try {
d7bc1a7a
FT
53 int d1 = in.read();
54 int d2 = in.read();
55 buf.append((byte)((Misc.hex2int((char)d1) << 4) | Misc.hex2int((char)d2)));
efa9722b
FT
56 } catch(NumberFormatException e) {
57 throw(new EncodingException("Invalid character escape"));
58 }
efa9722b
FT
59 } else if((c == '&') || (c == -1)) {
60 ret.add(key, buf.convert());
61 buf = new MixedBuffer();
62 st = "key";
63 } else if(c == '+') {
64 buf.append(' ');
65 } else {
66 buf.append((char)c);
67 }
68 }
69 }
70 return(ret);
71 } catch(CharacterCodingException e) {
72 throw(new EncodingException("Escaped parameter text is not proper UTF-8"));
73 }
74 }
75
d7bc1a7a
FT
76 public static MultiMap<String, String> urlparams(String q) {
77 try {
78 return(urlparams(new StringReader(q)));
79 } catch(IOException e) {
80 /* This will, of course, never ever once happen, but do
81 * you think Javac cares? */
82 throw(new Error(e));
83 }
84 }
85
efa9722b 86 public static MultiMap<String, String> urlparams(URL url) {
ca045757
FT
87 String q = url.getQuery();
88 if(q == null)
89 q = "";
90 return(urlparams(q));
efa9722b
FT
91 }
92
93 public static MultiMap<String, String> urlparams(Request req) {
94 return(urlparams(req.url()));
95 }
96
97 public static String encquery(Map<String, String> pars) {
98 StringBuilder buf = new StringBuilder();
99 boolean f = true;
100 for(Map.Entry<String, String> par : pars.entrySet()) {
101 if(!f)
102 buf.append('&');
103 buf.append(Misc.urlq(par.getKey()));
104 buf.append('=');
105 buf.append(Misc.urlq(par.getValue()));
106 f = false;
107 }
108 return(buf.toString());
109 }
ca045757
FT
110
111 public static MultiMap<String, String> postparams(Request req) {
112 if(req.method() != "POST")
113 return(null);
ca045757
FT
114 String ctype = req.inheaders().get("Content-Type");
115 if(ctype == null)
116 return(null);
117 ctype = ctype.toLowerCase();
118 if(ctype.equals("application/x-www-form-urlencoded")) {
ca045757
FT
119 byte[] data;
120 try {
d7bc1a7a 121 return(urlparams(new InputStreamReader(req.input(), "UTF-8")));
ca045757
FT
122 } catch(IOException e) {
123 return(null);
124 }
ca045757
FT
125 }
126 return(null);
127 }
80e2f848
FT
128
129 public static MultiMap<String, String> stdparams(Request req) {
130 MultiMap<String, String> params = Params.urlparams(req);
131 if(req.method() == "POST") {
132 MultiMap<String, String> pp = Params.postparams(req);
133 if(pp != null)
134 params.putAll(pp);
135 }
136 return(params);
137 }
efa9722b 138}