Class | Line # | Actions | |||
---|---|---|---|---|---|
HTTP | 35 | 44 | 14 |
1 | package org.json; | |
2 | ||
3 | /* | |
4 | Copyright (c) 2002 JSON.org | |
5 | ||
6 | Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | of this software and associated documentation files (the "Software"), to deal | |
8 | in the Software without restriction, including without limitation the rights | |
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | copies of the Software, and to permit persons to whom the Software is | |
11 | furnished to do so, subject to the following conditions: | |
12 | ||
13 | The above copyright notice and this permission notice shall be included in all | |
14 | copies or substantial portions of the Software. | |
15 | ||
16 | The Software shall be used for Good, not Evil. | |
17 | ||
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
24 | SOFTWARE. | |
25 | */ | |
26 | ||
27 | import java.util.Locale; | |
28 | ||
29 | /** | |
30 | * Convert an HTTP header to a JSONObject and back. | |
31 | * | |
32 | * @author JSON.org | |
33 | * @version 2015-12-09 | |
34 | */ | |
35 | public class HTTP | |
36 | { | |
37 | ||
38 | /** Carriage return/line feed. */ | |
39 | public static final String CRLF = "\r\n"; | |
40 | ||
41 | /** | |
42 | * Convert an HTTP header string into a JSONObject. It can be a request header | |
43 | * or a response header. A request header will contain | |
44 | * | |
45 | * <pre> | |
46 | * { | |
47 | * Method: "POST" (for example), | |
48 | * "Request-URI": "/" (for example), | |
49 | * "HTTP-Version": "HTTP/1.1" (for example) | |
50 | * } | |
51 | * </pre> | |
52 | * | |
53 | * A response header will contain | |
54 | * | |
55 | * <pre> | |
56 | * { | |
57 | * "HTTP-Version": "HTTP/1.1" (for example), | |
58 | * "Status-Code": "200" (for example), | |
59 | * "Reason-Phrase": "OK" (for example) | |
60 | * } | |
61 | * </pre> | |
62 | * | |
63 | * In addition, the other parameters in the header will be captured, using the | |
64 | * HTTP field names as JSON names, so that | |
65 | * | |
66 | * <pre> | |
67 | * Date: Sun, 26 May 2002 18:06:04 GMT | |
68 | * Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s | |
69 | * Cache-Control: no-cache | |
70 | * </pre> | |
71 | * | |
72 | * become | |
73 | * | |
74 | * <pre> | |
75 | * {... | |
76 | * Date: "Sun, 26 May 2002 18:06:04 GMT", | |
77 | * Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s", | |
78 | * "Cache-Control": "no-cache", | |
79 | * ...} | |
80 | * </pre> | |
81 | * | |
82 | * It does no further checking or conversion. It does not parse dates. It does | |
83 | * not do '%' transforms on URLs. | |
84 | * | |
85 | * @param string | |
86 | * An HTTP header string. | |
87 | * @return A JSONObject containing the elements and attributes of the XML | |
88 | * string. | |
89 | * @throws JSONException | |
90 | */ | |
91 | 0 | public static JSONObject toJSONObject(String string) throws JSONException |
92 | { | |
93 | 0 | JSONObject jo = new JSONObject(); |
94 | 0 | HTTPTokener x = new HTTPTokener(string); |
95 | 0 | String token; |
96 | ||
97 | 0 | token = x.nextToken(); |
98 | 0 | if (token.toUpperCase(Locale.ROOT).startsWith("HTTP")) |
99 | { | |
100 | ||
101 | // Response | |
102 | ||
103 | 0 | jo.put("HTTP-Version", token); |
104 | 0 | jo.put("Status-Code", x.nextToken()); |
105 | 0 | jo.put("Reason-Phrase", x.nextTo('\0')); |
106 | 0 | x.next(); |
107 | ||
108 | } | |
109 | else | |
110 | { | |
111 | ||
112 | // Request | |
113 | ||
114 | 0 | jo.put("Method", token); |
115 | 0 | jo.put("Request-URI", x.nextToken()); |
116 | 0 | jo.put("HTTP-Version", x.nextToken()); |
117 | } | |
118 | ||
119 | // Fields | |
120 | ||
121 | 0 | while (x.more()) |
122 | { | |
123 | 0 | String name = x.nextTo(':'); |
124 | 0 | x.next(':'); |
125 | 0 | jo.put(name, x.nextTo('\0')); |
126 | 0 | x.next(); |
127 | } | |
128 | 0 | return jo; |
129 | } | |
130 | ||
131 | /** | |
132 | * Convert a JSONObject into an HTTP header. A request header must contain | |
133 | * | |
134 | * <pre> | |
135 | * { | |
136 | * Method: "POST" (for example), | |
137 | * "Request-URI": "/" (for example), | |
138 | * "HTTP-Version": "HTTP/1.1" (for example) | |
139 | * } | |
140 | * </pre> | |
141 | * | |
142 | * A response header must contain | |
143 | * | |
144 | * <pre> | |
145 | * { | |
146 | * "HTTP-Version": "HTTP/1.1" (for example), | |
147 | * "Status-Code": "200" (for example), | |
148 | * "Reason-Phrase": "OK" (for example) | |
149 | * } | |
150 | * </pre> | |
151 | * | |
152 | * Any other members of the JSONObject will be output as HTTP fields. The | |
153 | * result will end with two CRLF pairs. | |
154 | * | |
155 | * @param jo | |
156 | * A JSONObject | |
157 | * @return An HTTP header string. | |
158 | * @throws JSONException | |
159 | * if the object does not contain enough information. | |
160 | */ | |
161 | 0 | public static String toString(JSONObject jo) throws JSONException |
162 | { | |
163 | 0 | StringBuilder sb = new StringBuilder(); |
164 | 0 | if (jo.has("Status-Code") && jo.has("Reason-Phrase")) |
165 | { | |
166 | 0 | sb.append(jo.getString("HTTP-Version")); |
167 | 0 | sb.append(' '); |
168 | 0 | sb.append(jo.getString("Status-Code")); |
169 | 0 | sb.append(' '); |
170 | 0 | sb.append(jo.getString("Reason-Phrase")); |
171 | } | |
172 | 0 | else if (jo.has("Method") && jo.has("Request-URI")) |
173 | { | |
174 | 0 | sb.append(jo.getString("Method")); |
175 | 0 | sb.append(' '); |
176 | 0 | sb.append('"'); |
177 | 0 | sb.append(jo.getString("Request-URI")); |
178 | 0 | sb.append('"'); |
179 | 0 | sb.append(' '); |
180 | 0 | sb.append(jo.getString("HTTP-Version")); |
181 | } | |
182 | else | |
183 | { | |
184 | 0 | throw new JSONException("Not enough material for an HTTP header."); |
185 | } | |
186 | 0 | sb.append(CRLF); |
187 | // Don't use the new entrySet API to maintain Android support | |
188 | 0 | for (final String key : jo.keySet()) |
189 | { | |
190 | 0 | String value = jo.optString(key); |
191 | 0 | if (!"HTTP-Version".equals(key) && !"Status-Code".equals(key) |
192 | && !"Reason-Phrase".equals(key) && !"Method".equals(key) | |
193 | && !"Request-URI".equals(key) | |
194 | && !JSONObject.NULL.equals(value)) | |
195 | { | |
196 | 0 | sb.append(key); |
197 | 0 | sb.append(": "); |
198 | 0 | sb.append(jo.optString(key)); |
199 | 0 | sb.append(CRLF); |
200 | } | |
201 | } | |
202 | 0 | sb.append(CRLF); |
203 | 0 | return sb.toString(); |
204 | } | |
205 | } |