KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > HTTPClient > ContentEncodingModule


1 /*
2  * @(#)ContentEncodingModule.java 0.3-2 18/06/1999
3  *
4  * This file is part of the HTTPClient package
5  * Copyright (C) 1996-1999 Ronald Tschalär
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free
19  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307, USA
21  *
22  * For questions, suggestions, bug-reports, enhancement-requests etc.
23  * I may be contacted at:
24  *
25  * ronald@innovation.ch
26  *
27  */

28
29 package HTTPClient;
30
31 import java.io.IOException JavaDoc;
32 import java.util.Vector JavaDoc;
33 import java.util.zip.InflaterInputStream JavaDoc;
34 import java.util.zip.GZIPInputStream JavaDoc;
35
36
37 /**
38  * This module handles the Content-Encoding response header. It currently
39  * handles the "gzip", "deflate", "compress" and "identity" tokens.
40  *
41  * Note: This module requires JDK 1.1 or later.
42  *
43  * @version 0.3-2 18/06/1999
44  * @author Ronald Tschalär
45  */

46
47 class ContentEncodingModule implements HTTPClientModule, GlobalConstants
48 {
49     static
50     {
51     /* This ensures that the loading of this class is only successful
52      * if we're in JDK 1.1 (or later) and have access to java.util.zip
53      */

54     try
55         { new InflaterInputStream JavaDoc(null); }
56     catch (NullPointerException JavaDoc npe)
57         { /* JDK 1.2 Final started throwing this */ }
58     }
59
60
61     // Constructors
62

63     ContentEncodingModule()
64     {
65     }
66
67
68     // Methods
69

70     /**
71      * Invoked by the HTTPClient.
72      */

73     public int requestHandler(Request req, Response[] resp)
74         throws ModuleException
75     {
76     // parse Accept-Encoding header
77

78     int idx;
79     NVPair[] hdrs = req.getHeaders();
80     for (idx=0; idx<hdrs.length; idx++)
81         if (hdrs[idx].getName().equalsIgnoreCase("Accept-Encoding"))
82         break;
83
84     Vector JavaDoc pae;
85     if (idx == hdrs.length)
86     {
87         hdrs = Util.resizeArray(hdrs, idx+1);
88         req.setHeaders(hdrs);
89         pae = new Vector JavaDoc();
90     }
91     else
92     {
93         try
94         { pae = Util.parseHeader(hdrs[idx].getValue()); }
95         catch (ParseException pe)
96         { throw new ModuleException(pe.toString()); }
97     }
98
99
100     // done if "*;q=1.0" present
101

102     HttpHeaderElement all = Util.getElement(pae, "*");
103     if (all != null)
104     {
105         NVPair[] params = all.getParams();
106         for (idx=0; idx<params.length; idx++)
107         if (params[idx].getName().equalsIgnoreCase("q")) break;
108
109         if (idx == params.length) // no qvalue, i.e. q=1.0
110
return REQ_CONTINUE;
111
112         if (params[idx].getValue() == null ||
113         params[idx].getValue().length() == 0)
114         throw new ModuleException("Invalid q value for \"*\" in " +
115                       "Accept-Encoding header: ");
116
117         try
118         {
119         if (Float.valueOf(params[idx].getValue()).floatValue() > 0.)
120             return REQ_CONTINUE;
121         }
122         catch (NumberFormatException JavaDoc nfe)
123         {
124         throw new ModuleException("Invalid q value for \"*\" in " +
125                 "Accept-Encoding header: " + nfe.getMessage());
126         }
127     }
128
129
130     // Add gzip, deflate and compress tokens to the Accept-Encoding header
131

132     if (!pae.contains(new HttpHeaderElement("deflate")))
133         pae.addElement(new HttpHeaderElement("deflate"));
134     if (!pae.contains(new HttpHeaderElement("gzip")))
135         pae.addElement(new HttpHeaderElement("gzip"));
136     if (!pae.contains(new HttpHeaderElement("x-gzip")))
137         pae.addElement(new HttpHeaderElement("x-gzip"));
138     if (!pae.contains(new HttpHeaderElement("compress")))
139         pae.addElement(new HttpHeaderElement("compress"));
140     if (!pae.contains(new HttpHeaderElement("x-compress")))
141         pae.addElement(new HttpHeaderElement("x-compress"));
142
143     hdrs[idx] = new NVPair("Accept-Encoding", Util.assembleHeader(pae));
144
145     return REQ_CONTINUE;
146     }
147
148
149     /**
150      * Invoked by the HTTPClient.
151      */

152     public void responsePhase1Handler(Response resp, RoRequest req)
153     {
154     }
155
156
157     /**
158      * Invoked by the HTTPClient.
159      */

160     public int responsePhase2Handler(Response resp, Request req)
161     {
162     return RSP_CONTINUE;
163     }
164
165
166     /**
167      * Invoked by the HTTPClient.
168      */

169     public void responsePhase3Handler(Response resp, RoRequest req)
170         throws IOException JavaDoc, ModuleException
171     {
172     String JavaDoc ce = resp.getHeader("Content-Encoding");
173     if (ce == null || req.getMethod().equals("HEAD") ||
174         resp.getStatusCode() == 206)
175         return;
176
177     Vector JavaDoc pce;
178     try
179         { pce = Util.parseHeader(ce); }
180     catch (ParseException pe)
181         { throw new ModuleException(pe.toString()); }
182
183     if (pce.size() == 0)
184         return;
185
186     String JavaDoc encoding = ((HttpHeaderElement) pce.firstElement()).getName();
187     if (encoding.equalsIgnoreCase("gzip") ||
188         encoding.equalsIgnoreCase("x-gzip"))
189     {
190         if (DebugMods)
191         System.err.println("CEM: pushing gzip-input-stream");
192
193         resp.inp_stream = new GZIPInputStream JavaDoc(resp.inp_stream);
194         pce.removeElementAt(pce.size()-1);
195         resp.deleteHeader("Content-length");
196     }
197     else if (encoding.equalsIgnoreCase("deflate"))
198     {
199         if (DebugMods)
200         System.err.println("CEM: pushing inflater-input-stream");
201
202         resp.inp_stream = new InflaterInputStream JavaDoc(resp.inp_stream);
203         pce.removeElementAt(pce.size()-1);
204         resp.deleteHeader("Content-length");
205     }
206     else if (encoding.equalsIgnoreCase("compress") ||
207          encoding.equalsIgnoreCase("x-compress"))
208     {
209         if (DebugMods)
210         System.err.println("CEM: pushing uncompress-input-stream");
211
212         resp.inp_stream = new UncompressInputStream(resp.inp_stream);
213         pce.removeElementAt(pce.size()-1);
214         resp.deleteHeader("Content-length");
215     }
216     else if (encoding.equalsIgnoreCase("identity"))
217     {
218         if (DebugMods)
219         System.err.println("CEM: ignoring 'identity' token");
220         pce.removeElementAt(pce.size()-1);
221     }
222     else
223     {
224         if (DebugMods)
225         System.err.println("CEM: Unknown content encoding '" +
226                     encoding + "'");
227     }
228
229     if (pce.size() > 0)
230         resp.setHeader("Content-Encoding", Util.assembleHeader(pce));
231     else
232         resp.deleteHeader("Content-Encoding");
233     }
234
235
236     /**
237      * Invoked by the HTTPClient.
238      */

239     public void trailerHandler(Response resp, RoRequest req)
240     {
241     }
242 }
243
244
Popular Tags