WebServerConnection.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2006 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: pdelrieu@openmobileis.org
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00020  * USA
00021  *
00022  *  Author : Philippe Delrieu
00023  *  
00024  *  Modifications :
00025  *  2004 Creation P.Delrieu
00026  *  2004 Modified by Romain Beaugrand
00027  * 
00028  */
00029 
00030 package org.openmobileis.embedded.webserver;
00031 
00032 import java.io.BufferedOutputStream;
00033 import java.io.BufferedReader;
00034 import java.io.ByteArrayOutputStream;
00035 import java.io.File;
00036 import java.io.FileOutputStream;
00037 import java.io.IOException;
00038 import java.io.InputStreamReader;
00039 import java.io.OutputStream;
00040 import java.io.OutputStreamWriter;
00041 import java.io.PrintWriter;
00042 import java.io.UnsupportedEncodingException;
00043 import java.net.InetAddress;
00044 import java.net.Socket;
00045 import java.security.Principal;
00046 import java.text.SimpleDateFormat;
00047 import java.util.Date;
00048 import java.util.Enumeration;
00049 import java.util.Hashtable;
00050 import java.util.Locale;
00051 import java.util.StringTokenizer;
00052 import java.util.Vector;
00053 
00054 import javax.servlet.RequestDispatcher;
00055 import javax.servlet.ServletException;
00056 import javax.servlet.ServletInputStream;
00057 import javax.servlet.ServletOutputStream;
00058 import javax.servlet.ServletRequest;
00059 import javax.servlet.ServletResponse;
00060 import javax.servlet.SingleThreadModel;
00061 import javax.servlet.http.Cookie;
00062 import javax.servlet.http.HttpServlet;
00063 import javax.servlet.http.HttpServletRequest;
00064 import javax.servlet.http.HttpServletResponse;
00065 import javax.servlet.http.HttpSession;
00066 
00067 
00068 import org.apache.commons.fileupload.MultipartStream;
00069 import org.openmobileis.common.context.SessionContext;
00070 import org.openmobileis.common.context.SessionContextManager;
00071 import org.openmobileis.common.util.log.LogManager;
00072 import org.openmobileis.common.util.log.LogServices;
00073 
00074 public class WebServerConnection implements HttpServletRequest, HttpServletResponse {
00075 
00076         public final static String WWWFORMURLENCODE = "application/x-www-form-urlencoded";
00077         public final static String WWWMULTIPARTURLENCODE = "multipart/form-data";
00078         public final static String TRANSFERENCODING = "Transfer-Encoding";
00079         public final static String CHUNKED = "chunked";
00080         public final static String CONTENTLENGTH = "Content-Length";
00081         public final static String CONTENTTYPE = "Content-Type";
00082 
00083         private Socket socket;
00084         private WebServer webserver;
00085 
00086         private String reqMethod; // == null by default
00087 
00088         private String reqUriPath;
00089 
00090         private boolean oneOne; // HTTP/1.1 or better
00091 
00092         String reqQuery = null;
00093 
00094         private Vector reqHeaderNames = new Vector();
00095         private Vector reqHeaderValues = new Vector();
00096         private Locale locale; // = java.util.Locale.getDefault();
00097 
00098         private int uriLen;
00099         private static final Hashtable EMPTYHASHTABLE = new Hashtable(10);
00100 
00101         protected long connexionLifeTime = 0;
00102 
00103         private ServletInputStream in;
00104 
00105         private ServletOutputStream out;
00106 
00107         private boolean reqMime;
00108 
00109         private String reqProtocol;
00110         private String reqCharEncoding;
00111 
00112         private Hashtable formParameters = new Hashtable(10);
00113 
00114         private Hashtable attributes = new Hashtable(10);
00115 
00116         private int resCode = -1;
00117 
00118         private String resMessage = null;
00119 
00120         private Hashtable resHeaderNames = new Hashtable(10);
00121 
00122         private boolean headersWritten = false;
00123 
00124         protected static final SimpleDateFormat expdatefmt = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss 'GMT'");
00125 
00126         protected static final SimpleDateFormat headerdateformat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
00127 
00128         private PrintWriter printWriter = null;
00129         
00130         private String defaultCharacterEncoding;
00131         
00132         private boolean hasUrlDecoder = true;
00133 
00134         public WebServerConnection() {
00135                 super();
00136         }
00137 
00138         public void init(WebServer webserver, Socket socket) {
00139                 // Save arguments.
00140                 this.webserver = webserver;
00141                 this.socket = socket;
00142                 out = null;
00143                 in = null;
00144                 oneOne = false;
00145                 reqMethod = null;
00146                 reqUriPath = null;
00147                 reqQuery = null;
00148                 reqProtocol = null;
00149                 reqCharEncoding = null;
00150                 reqHeaderNames = new Vector();
00151                 reqHeaderValues = new Vector();
00152                 formParameters = null;
00153                 attributes = new Hashtable();
00154                 locale = null;
00155                 uriLen = -1;
00156                 resCode = -1;
00157                 connexionLifeTime = 0;
00158                 reqMime = false;
00159                 resMessage = "";
00160                 resHeaderNames = new Hashtable();
00161                 headersWritten = false;
00162                 printWriter = null;
00163                 this.defaultCharacterEncoding = System.getProperty("file.encoding");
00164                 try     {
00165                         String test = java.net.URLDecoder.decode("", "UTF-8");
00166                 } catch (Throwable ex){
00167                         hasUrlDecoder = false;
00168                 }
00169                 
00170         }
00171 
00172         // Methods from Runnable.
00173         public void run() {
00174                 SessionContextManager.getManager().joinSessionContext("OPENMOBILEISSESSION");
00175                 try {
00176                         // Get the streams.
00177                         in = new ServeInputStream(socket.getInputStream());
00178                         out = new ServeOutputStream(socket.getOutputStream(), this);
00179                 } catch (IOException e) {
00180                         problem("Getting streams: " + e.getMessage(), SC_BAD_REQUEST);
00181                         LogManager.traceError(0, e.toString());
00182                         try {
00183                                 socket.close();
00184                         } catch (Exception ex) {
00185                         }
00186                         return;
00187                 }
00188 
00189                 // parse the request
00190                 parseRequest();
00191 
00192                 // LogManager.traceDebug(LogServices.WEBSERVICE,
00193                 // socket.getInetAddress().toString()
00194                 // + ' ' + reqMethod + ' ' + reqUriPath + ' ' + resCode
00195                 /*
00196                  * + (serve.isShowReferer() ? "| " + getHeader("Referer") : "") +
00197                  * (serve.isShowUserAgent() ? "| " + getHeader("User-Agent") : "")
00198                  */
00199                 // );
00200                 try {
00201                         this.execURI(this.reqUriPath);
00202                 } catch (Exception e) {
00203                         problem("Getting streams: " + e.getMessage(), SC_BAD_REQUEST);
00204                         LogManager.traceError(0, e);
00205                 } finally {
00206                         try {
00207                                 // socket.getOutputStream().write(byteOut.toByteArray());
00208                                 socket.close();
00209                         } catch (IOException e) {
00210                                 org.openmobileis.common.util.log.LogManager.traceError(org.openmobileis.common.util.log.LogServices.WEBSERVICE,
00211                                                 "Impossible to close socket : WebServerConnection");
00212                                 org.openmobileis.common.util.log.LogManager.traceError(org.openmobileis.common.util.log.LogServices.WEBSERVICE, e);
00213                         }
00214                 }
00215         }
00216 
00217         private void parseRequest() {
00218                 byte[] lineBytes = new byte[4096];
00219                 int len;
00220                 String line;
00221 
00222                 try {
00223                         // Read the first line of the request.
00224 
00225                         len = in.readLine(lineBytes, 0, lineBytes.length);
00226                         if (len == -1 || len == 0) {
00227                                 problem("Empty request", SC_BAD_REQUEST);
00228                                 return;
00229                         }
00230                         line = new String(lineBytes, 0, len);
00231                         StringTokenizer ust = new StringTokenizer(line);
00232                         reqProtocol = null;
00233                         if (ust.hasMoreTokens()) {
00234                                 reqMethod = ust.nextToken();
00235                                 if (ust.hasMoreTokens()) {
00236                                         reqUriPath = ust.nextToken(); // Acme.Utils.urlDecoder(ust.nextToken());
00237                                         if (ust.hasMoreTokens()) {
00238                                                 reqProtocol = ust.nextToken();
00239                                                 oneOne = !reqProtocol.toUpperCase().equals("HTTP/1.0");
00240                                                 reqMime = true;
00241                                                 // Read the rest of the lines.
00242                                                 String s;
00243                                                 while ((s = ((ServeInputStream) in).readLine()) != null) {
00244                                                         if (s.length() == 0)
00245                                                                 break;
00246 
00247                                                         int c = s.indexOf(':', 0);
00248                                                         if (c > 0) {
00249                                                                 String key = s.substring(0, c).trim();
00250                                                                 String value = s.substring(c + 1, s.length()).trim();
00251                                                                 reqHeaderNames.addElement(key.toLowerCase());
00252                                                                 reqHeaderValues.addElement(value);
00253                                                         } else {
00254                                                                 LogManager.traceError(LogServices.WEBSERVICE, "header field without ':'");
00255                                                         }
00256                                                 }
00257                                         } else {
00258                                                 reqProtocol = "HTTP/0.9";
00259                                                 oneOne = false;
00260                                                 reqMime = false;
00261                                         }
00262                                 }
00263                         }
00264                         if (reqProtocol == null) {
00265                                 problem("Malformed request line", SC_BAD_REQUEST);
00266                                 return;
00267                         }
00268                         // Check Host: header in HTTP/1.1 requests.
00269                         if (oneOne) {
00270                                 String host = getHeader("host");
00271                                 if (host == null) {
00272                                         problem("Host header missing on HTTP/1.1 request", SC_BAD_REQUEST);
00273                                         return;
00274                                 }
00275                         }
00276 
00277                         // Decode %-sequences.
00278                         // reqUriPath = decode( reqUriPath );
00279                         // Split off query string, if any.
00280                         int qmark = reqUriPath.indexOf('?');
00281                         if (qmark > -1) {
00282                                 reqQuery = reqUriPath.substring(qmark + 1);
00283                                 reqUriPath = reqUriPath.substring(0, qmark);
00284                         }
00285                         if (CHUNKED.equals(getHeader(TRANSFERENCODING))) {
00286                                 setHeader(CONTENTLENGTH, null);
00287                                 ((ServeInputStream) in).chunking(true);
00288                         }
00289 
00290                 } catch (IOException e) {
00291                         problem("Reading request: " + e.getMessage(), SC_BAD_REQUEST);
00292                 }
00293         }
00294 
00295         private void execURI(String URI) throws ServletException {
00296                 // manage /index for index servlet
00297                 if (URI.equals("/index")) {
00298                         URI = "/services/index";
00299                         reqUriPath = URI;
00300                 }
00301                 Object[] os = webserver.getServletByURLorClassName(URI);
00302                 if (os[0] == null) {
00303                         os = webserver.getServletByURLorClassName("defaultServlet");
00304                         if (os[0] == null) {
00305                                 throw new ServletException("WebServerConnection::execUri Unable to find file servlet");
00306                         }
00307                         // uriLen = ((Integer) os[1]).intValue();
00308                         uriLen = 0;
00309                         runServlet((HttpServlet) os[0]);
00310                 } else {
00311                         uriLen = ((Integer) os[1]).intValue();
00312                         runServlet((HttpServlet) os[0]);
00313                 }
00314         }
00315 
00316         // / Writes the status line and message headers for this response to the
00317         // output stream.
00318         // @exception IOException if an I/O error has occurred
00319         void writeHeaders() throws IOException {
00320                 synchronized (this) {
00321                         if (headersWritten)
00322                                 return;
00323 
00324                         headersWritten = true;
00325                 }
00326                 if (reqMime) {
00327                         // boolean chunked_out = false;
00328                         out.println(reqProtocol + " " + resCode + " " + resMessage);
00329 
00330                         Enumeration he = resHeaderNames.keys();
00331                         while (he.hasMoreElements()) {
00332                                 String name = (String) he.nextElement();
00333                                 Object o = resHeaderNames.get(name);
00334                                 if (o instanceof String) {
00335                                         String value = (String) o;
00336                                         if (value != null) // just in case
00337                                                 out.println(name + ": " + value);
00338                                         /*
00339                                          * moved to servlet if (TRANSFERENCODING.equals(name) &&
00340                                          * CHUNKED.equals(value)) chunked_out = true;
00341                                          */
00342                                 } else if (o instanceof String[]) {
00343                                         String[] values = (String[]) o;
00344                                         out.println(name + ": " + values[0]);
00345                                         for (int i = 0; i < values.length; i++)
00346                                                 out.print("," + values[i]);
00347                                         out.println();
00348                                 }
00349                         }
00350                         
00351                 //      out.println("Content-Type: text/html; charset=ISO-8859-1");
00352 
00353                         // add specific header to remove page from cache
00354                         out.println("Pragma: no-cache");
00355                         out.println("Cache-Control: no-cache, must-revalidate");
00356                         out.println("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
00357                         out.println("Date: Mon, 26 Jul 1997 05:00:00 GMT");
00358 
00359                         out.println("Last-Modified: Mon, 26 Jul 1997 05:00:00 GMT");
00360                         out.println("Connection: close");
00361                         // Marks the beginning of body-content.
00362                         out.println();
00363                         out.flush();
00364                         // if (chunked_out) ((ServeOutputStream)out).setChunked(true);
00365                 }
00366         }
00367 
00368         private void runServlet(HttpServlet servlete) {
00369                 // Set default response fields.
00370                 setStatus(SC_OK);
00371                 /*
00372                  * setDateHeader("Date", System.currentTimeMillis()); setHeader("Server",
00373                  * Serve.Identification.serverName + "/" +
00374                  * Serve.Identification.serverVersion); setHeader("MIME-Version", "1.0");
00375                  */
00376                 try {
00377                         authenticate();
00378                         ((SessionContext) this.getSession()).setServletContext(servlete.getServletConfig().getServletContext());
00379                         if (servlete instanceof SingleThreadModel)
00380                                 synchronized (servlete) {
00381                                         servlete.service((ServletRequest) this, (ServletResponse) this);
00382                                 }
00383                         else {
00384                                 servlete.service((ServletRequest) this, (ServletResponse) this);
00385                         }
00386                         if (((ServeOutputStream) out).isReturnedAsWriter() && printWriter != null) {
00387                                 printWriter.flush();
00388                         } else {
00389                                 out.flush();
00390                         }
00391                 } catch (IOException e) {
00392                         e.printStackTrace();
00393                         problem("IO problem running servlet: " + e.toString(), SC_BAD_REQUEST);
00394                 } catch (ServletException e) {
00395                         e.printStackTrace();
00396                         problem("problem running servlet: " + e.toString(), SC_BAD_REQUEST);
00397                 } catch (Exception e) {
00398                         e.printStackTrace();
00399                         problem("unexpected problem running servlet: " + e.toString(), SC_INTERNAL_SERVER_ERROR);
00400                 }
00401         }
00402 
00403         private boolean authenticate() throws IOException {
00404                 // We don't use any authentification
00405                 return true;
00406         }
00407 
00408         // send an error page
00409         private void problem(String logMessage, int resCode) {
00410                 LogManager.traceError(LogServices.WEBSERVICE, logMessage);
00411                 try {
00412                         sendError(resCode);
00413                 } catch (IllegalStateException e) { /* ignore */
00414                 } catch (IOException e) { /* ignore */
00415                 }
00416         }
00417 
00425         private Hashtable parseQueryString(String queryString) throws UnsupportedEncodingException {
00426                 Hashtable map = new Hashtable();
00427 
00428                 StringTokenizer token = new StringTokenizer(queryString, "&");
00429                 while (token.hasMoreTokens()) {
00430                         String tok = token.nextToken();
00431                         int index = tok.indexOf('=');
00432                         if (index == -1) {
00433                                 // "invalid url parameter " + parameters[i]);
00434                                 continue;
00435                         }
00436                         String key = Acme.Utils.urlDecoder(tok.substring(0, index));
00437                         String value = null;
00438                         if(hasUrlDecoder)       {
00439                                 String encoding = this.defaultCharacterEncoding;
00440                                 if (encoding == null) encoding = "UTF-8";
00441                                 String valueToDecode = tok.substring(index + 1, tok.length());
00442                                 value = java.net.URLDecoder.decode(valueToDecode, encoding);
00443 
00444                                 if (this.detectBadURLDecoding(value))   { // bad query encoding. If default is UTF8 try with ISO. 
00445                                         if ( encoding.equals("UTF-8")) value = java.net.URLDecoder.decode(valueToDecode, "ISO-8859-1");
00446                                         else value = java.net.URLDecoder.decode(valueToDecode, "UTF-8"); // try UTF8
00447                                 }
00448                         } else  {
00449                                 value = Acme.Utils.urlDecoder(tok.substring(index + 1, tok.length()));
00450                         }
00451                         
00452                         if (map.containsKey(key)) {
00453                                 String[] oldValue = (String[]) map.get(key);
00454                                 String[] newValue = new String[oldValue.length + 1];
00455                                 System.arraycopy(oldValue, 0, newValue, 0, oldValue.length);
00456                                 newValue[oldValue.length] = value;
00457                                 map.put(key, newValue);
00458                         } else {
00459                                 map.put(key, new String[] { value });
00460                         }
00461                 }
00462 
00463                 return map;
00464         }
00465         
00466         private boolean detectBadURLDecoding(String value)      {
00467                 char[] buff = value.toCharArray();
00468                 for (int i=0; i<buff.length; i++)       {
00469                         if (((int)buff[i]) == 65533)    {
00470                                 return true;
00471                         }
00472                 }
00473                 return false;
00474         }
00475 
00476         private Hashtable getParametersFromRequest() {
00477                 Hashtable result = null;
00478                 // System.out.println("Req:"+reqMethod+" con:"+getContentType()+" eq
00479                 // "+WWWFORMURLENCODE.equals(getContentType()));
00480                 if ("GET".equals(reqMethod)) {
00481                         if (reqQuery != null)
00482                                 try {
00483                                         result = this.parseQueryString(reqQuery);
00484                                 } catch (Exception ex) {
00485                                         LogManager.traceError(LogServices.WEBSERVICE, "Exception " + ex.toString() + " Error parsing query strind");
00486                                 }
00487                 } else if ("POST".equals(reqMethod)) {
00488                         if (WWWFORMURLENCODE.equals(getContentType())) {
00489                                 try {
00490                                 //      result = HttpUtils.parsePostData(getContentLength(), getInputStream());
00491                                         result = this.parsePostData(getContentLength(), getInputStream(), null);
00492 
00493                                         if (reqQuery != null && reqQuery.length() > 0) {
00494                                                 Acme.Utils.putAll(result, parseQueryString(reqQuery));
00495                                         }
00496                                 } catch (Exception ex) {
00497                                         LogManager.traceError(LogServices.WEBSERVICE, "Exception " + ex.toString() + " at parsing post data of length " + getContentLength());
00498                                 }
00499                         } else if (this.getContentType().startsWith(WWWMULTIPARTURLENCODE)) { //get multipart data.
00500                                 //get moudary.
00501                                 String contentType = this.getContentType(); //multipart/form-data; boundary=---------------------------80953939213117444377387769
00502                                 int boundaryIndex = contentType.indexOf("boundary=");
00503                                 if (boundaryIndex > 0) {
00504                                         try {
00505                                                 result = new Hashtable();
00506                                                 byte[] boundary = contentType.substring(boundaryIndex + 9).getBytes();
00507                                                 MultipartStream multi = new MultipartStream(getInputStream(), boundary);
00508                                                 //            multi.setHeaderEncoding(headerEncoding);
00509                                                 boolean nextPart = multi.skipPreamble();
00510                                                 while (nextPart) {
00511                                                         String header = multi.readHeaders(); //Content-Disposition: form-data; name="attachedfile"; filename="README.2.95.3"
00512                                                         //Content-Type: application/octet-stream
00513                                                         //parse HEADER
00514                                                         int index = header.indexOf("form-data;");
00515                                                         String paramName = null;
00516                                                         String fileName = null;
00517                                                         if (index > 0) {
00518                                                                 header = header.substring(index + 10, header.length());
00519                                                                 index = header.indexOf("name=");
00520                                                                 if (index > 0) {
00521                                                                         header = header.substring(index + 6, header.length());
00522                                                                         index = header.indexOf('"');
00523                                                                         if (index > 0) {
00524                                                                                 paramName = header.substring(0, index);
00525                                                                         }
00526                                                                         index = header.indexOf("filename=");
00527                                                                         if (index > 0) {
00528                                                                                 header = header.substring(index + 10, header.length());
00529                                                                                 index = header.indexOf('"');
00530                                                                                 if (index > 0) {
00531                                                                                         fileName = header.substring(0, index);
00532                                                                                         //                                      result.put("filename", new String[] { fileName });                              
00533                                                                                 }
00534                                                                         }
00535                                                                 }
00536                                                         }
00537 
00538                                                         OutputStream out = null;
00539                                                         if (fileName != null) {
00540                                                                 String path = System.getProperty("user.dir") + File.separator + "temp";
00541                                                                 File dirtmp = new File(path);
00542                                                                 if (!dirtmp.exists())
00543                                                                         dirtmp.mkdirs();
00544                                                                 fileName = path + File.separator + fileName;
00545                                                                 out = new BufferedOutputStream(new FileOutputStream(fileName));
00546                                                         } else {
00547                                                                 out = new ByteArrayOutputStream();
00548                                                         }
00549 
00550                                                         multi.readBodyData(out);
00551                                                         out.flush();
00552                                                         out.close();
00553                                                         if (fileName != null && paramName != null) {
00554                                                                 result.put(paramName, new String[] { fileName });
00555                                                         } else if (paramName != null) {
00556                                                                 //                      if (header.indexOf("application/octet-stream") > 0)     {
00557                                                                 result.put(paramName, new String[] { out.toString() });
00558                                                         }
00559                                                         nextPart = multi.readBoundary();
00560                                                 }
00561 
00562                                         } catch (Throwable ex) {
00563                                                 LogManager.traceError(LogServices.WEBSERVICE, "Exception " + ex.toString() + " Error parsing multipart query strind");
00564                                         }
00565                                 }
00566                         }
00567                 } else {
00568                         try {
00569                                 if (reqQuery != null)
00570                                         result = parseQueryString(reqQuery);
00571                         } catch (Exception ex) {
00572                                 LogManager.traceError(LogServices.WEBSERVICE, "Exception " + ex.toString() + " Error parsing query strind");
00573                         }
00574                 }
00575                 return result != null ? result : EMPTYHASHTABLE;
00576         }
00577 
00578         private Hashtable parsePostData(int len, ServletInputStream in, String encoding) {
00579                 if (len <= 0)
00580                         return new Hashtable();
00581                 //
00582                 // Make sure we read the entire POSTed body.
00583                 //
00584                 byte[] postedBytes = new byte[len];
00585                 try {
00586                         int offset = 0;
00587                         do {
00588                                 int inputLen = in.read(postedBytes, offset, len - offset);
00589                                 if (inputLen <= 0) {
00590                                         throw new IllegalArgumentException("Error during servlet input stream read");
00591                                 }
00592                                 offset += inputLen;
00593                         } while ((len - offset) > 0);
00594 
00595                 } catch (IOException e) {
00596                         throw new IllegalArgumentException(e.getMessage());
00597                 }
00598 
00599                 // XXX we shouldn't assume that the only kind of POST body
00600                 // is FORM data encoded using ASCII or ISO Latin/1 ... or
00601                 // that the body should always be treated as FORM data.
00602                 //
00603 
00604                 try {
00605                         String postedBody = new String(postedBytes, 0, len);   //encoding , "8859_1"
00606                         return parseQueryString(postedBody);
00607                 } catch (java.io.UnsupportedEncodingException e) {
00608                         // XXX function should accept an encoding parameter & throw this
00609                         // exception.  Otherwise throw something expected.
00610                         throw new IllegalArgumentException(e.getMessage());
00611                 }
00612         }
00613 
00614         private void realSendError() throws IOException {
00615                 if (isCommitted())
00616                         throw new IllegalStateException("Can not send error, headers have been already written");
00617                 synchronized (out) {
00618                         // no more out after error
00619                         ((ServeOutputStream) out).setReturnedAsStream(true);
00620                         ((ServeOutputStream) out).setReturnedAsWriter(true);
00621                 }
00622                 setContentType("text/html");
00623                 StringBuffer sb = new StringBuffer(100);
00624                 sb.append("<HTML><HEAD>").append("<TITLE>" + resCode + " " + resMessage + "</TITLE>").append("</HEAD><BODY BGCOLOR=\"#F1D0F2\">").append(
00625                                 "<H2>" + resCode + " " + resMessage + "</H2>").append("<HR>");
00626                 Identification.writeAddress(sb);
00627                 sb.append("</BODY></HTML>");
00628                 setContentLength(sb.length());
00629                 out.print(sb.toString());
00630                 out.flush();
00631         }
00632 
00633         // HttpServletRequest METHODS
00634         // ***************************************************************************************************************
00635 
00636         // / Returns the value of the named attribute of the request, or null if
00637         // the attribute does not exist. This method allows access to request
00638         // information not already provided by the other methods in this interface.
00639         public Object getAttribute(String name) {
00640                 return attributes.get(name);
00641         }
00642 
00643         // from ServletRequest
00644         public Enumeration getAttributeNames() {
00645                 return attributes.keys();
00646         }
00647 
00648         public String getAuthType() {
00649                 // return HttpServletRequest.BASIC_AUTH;
00650                 return null;
00651         }
00652 
00653         // / Returns the size of the request entity data, or -1 if not known.
00654         // Same as the CGI variable CONTENT_LENGTH.
00655         public int getContentLength() {
00656                 try {
00657                         return this.getIntHeader(CONTENTLENGTH);
00658                 } catch (Exception ex) {
00659                         return -1;
00660                 }
00661         }
00662 
00663         // / Returns the MIME type of the request entity data, or null if
00664         // not known.
00665         // Same as the CGI variable CONTENT_TYPE.
00666         public String getContentType() {
00667                 return getHeader(CONTENTTYPE);
00668         }
00669 
00670         public String getContextPath() {
00671                 return "";
00672         }
00673 
00674         public Cookie[] getCookies() {
00675                 // We don't use cookies
00676                 return null;
00677         }
00678 
00679         public long getDateHeader(String name) {
00680                 String val = getHeader(name);
00681                 if (val == null)
00682                         return 0;
00683                 try {
00684                         return headerdateformat.parse(val).getTime();
00685                 } catch (Exception e) {
00686                         throw new IllegalArgumentException("Value " + val + " can't be converted to Date using " + headerdateformat.toPattern());
00687                 }
00688         }
00689 
00690         public String getHeader(String name) {
00691                 int i = reqHeaderNames.indexOf(name.toLowerCase());
00692                 if (i == -1)
00693                         return null;
00694                 return (String) reqHeaderValues.elementAt(i);
00695         }
00696 
00697         public Enumeration getHeaderNames() {
00698                 return reqHeaderNames.elements();
00699         }
00700 
00701         public Enumeration getHeaders(String header) {
00702                 Vector result = new Vector();
00703                 int i = -1;
00704                 while ((i = reqHeaderNames.indexOf(header.toLowerCase(), i + 1)) >= 0)
00705                         result.addElement(reqHeaderValues.elementAt(i));
00706                 return result.elements();
00707         }
00708 
00709         // / Returns an input stream for reading request data.
00710         // @exception IllegalStateException if getReader has already been called
00711         // @exception IOException on other I/O-related errors
00712         public ServletInputStream getInputStream() throws IOException {
00713                 synchronized (in) {
00714                         if (((ServeInputStream) in).isReturnedAsReader())
00715                                 throw new IllegalStateException("Already returned as a reader.");
00716                         ((ServeInputStream) in).setReturnedAsReader(true);
00717                 }
00718                 return in;
00719         }
00720 
00721         // / Returns the value of an integer header field.
00722         // @param name the header field name
00723         public int getIntHeader(String name) {
00724                 String val = getHeader(name);
00725                 if (val == null)
00726                         return -1;
00727 
00728                 // We don't use any try catch, as this method must return
00729                 // a NumberFormatException in case of problem
00730                 // (According to the Servlet 2.4 specifications)
00731                 return Integer.parseInt(val);
00732         }
00733 
00744         public String getLocalAddr() {
00745                 return null; // TODO:
00746         }
00747 
00748         // should decide about supported locales and charsets, no a good decision yet
00749         public Enumeration getLocales() {
00750                 // TODO: get locales from Accept-Language (RFC 2616)
00751                 // Locale.getAvailableLocales()
00752                 return null;
00753         }
00754 
00764         public String getLocalName() {
00765                 return null; // TODO: get bind address
00766         }
00767 
00776         public int getLocalPort() {
00777                 return webserver.port;
00778         }
00779 
00780         public String getMethod() {
00781                 return reqMethod;
00782         }
00783 
00784         // / Returns the value of the specified query string parameter, or null
00785         // if not found.
00786         // @param name the parameter name
00787         public String getParameter(String name) {
00788                 String[] params = getParameterValues(name);
00789                 if (params == null || params.length == 0)
00790                         return null;
00791 
00792                 return params[0];
00793         }
00794 
00806         public java.util.Map getParameterMap() {
00807                 return (java.util.Map) formParameters;
00808         }
00809 
00810         // / Returns the parameter names for this request.
00811         public Enumeration getParameterNames() {
00812                 if (formParameters == null)
00813                         formParameters = getParametersFromRequest();
00814                 return formParameters.keys();
00815         }
00816 
00817         // / Returns the values of the specified parameter for the request as an
00818         // array of strings, or null if the named parameter does not exist.
00819         public String[] getParameterValues(String name) {
00820                 if (formParameters == null)
00821                         getParameterNames();
00822 
00823                 return (String[]) formParameters.get(name);
00824         }
00825 
00826         public String getPathInfo() {
00827                 // In this server, the entire path is regexp-matched against the
00828                 // servlet pattern, so there's no good way to distinguish which
00829                 // part refers to the servlet.
00830                 return uriLen >= reqUriPath.length() ? null : reqUriPath.substring(uriLen);
00831         }
00832 
00833         public String getPathTranslated() {
00834                 // In this server, the entire path is regexp-matched against the
00835                 // servlet pattern, so there's no good way to distinguish which
00836                 // part refers to the servlet.
00837                 return getRealPath(getPathInfo());
00838         }
00839 
00840         // / Returns the protocol and version of the request as a string of
00841         // the form <protocol>/<major version>.<minor version>.
00842         // Same as the CGI variable SERVER_PROTOCOL.
00843         public String getProtocol() {
00844                 return reqProtocol;
00845         }
00846 
00847         // Returns the query string part of the servlet URI, or null if not known.
00848         // Same as the CGI variable QUERY_STRING.
00849         public String getQueryString() {
00850                 return reqQuery;
00851         }
00852 
00853         // / Returns a buffered reader for reading request data.
00854         // @exception UnsupportedEncodingException if the character set encoding isn't
00855         // supported
00856         // @exception IllegalStateException if getInputStream has already been called
00857         // @exception IOException on other I/O-related errors
00858         public BufferedReader getReader() throws IOException {
00859                 synchronized (in) {
00860                         if (((ServeInputStream) in).isReturnedAsStream())
00861                                 throw new IllegalStateException("Already returned as a stream.");
00862                         ((ServeInputStream) in).setReturnedAsStream(true);
00863                 }
00864                 if (reqCharEncoding != null)
00865                         try {
00866                                 return new BufferedReader(new InputStreamReader(in, reqCharEncoding));
00867                         } catch (UnsupportedEncodingException uee) {
00868                         }
00869                 return new BufferedReader(new InputStreamReader(in));
00870         }
00871 
00872         // / Applies alias rules to the specified virtual path and returns the
00873         // corresponding real path, or null if the translation can not be
00874         // performed for any reason. For example, an HTTP servlet would
00875         // resolve the path using the virtual docroot, if virtual hosting is
00876         // enabled, and with the default docroot otherwise. Calling this
00877         // method with the string "/" as an argument returns the document root.
00878         public String getRealPath(String path) {
00879                 return webserver.getRealPath(path);
00880         }
00881 
00882         // / Returns the IP address of the agent that sent the request.
00883         // Same as the CGI variable REMOTE_ADDR.
00884         public String getRemoteAddr() {
00885                 return socket.getInetAddress().getHostAddress().toString();
00886         }
00887 
00888         // / Returns the fully qualified host name of the agent that sent the
00889         // request.
00890         // Same as the CGI variable REMOTE_HOST.
00891         public String getRemoteHost() {
00892                 String result = socket.getInetAddress().getHostName();
00893                 return result != null ? result : getRemoteAddr();
00894         }
00895 
00904         public int getRemotePort() {
00905                 // TODO : Actually returns local port
00906                 return webserver.port;
00907         }
00908 
00909         // / Returns the name of the user making this request, or null if not known.
00910         // Same as the CGI variable REMOTE_USER.
00911         public String getRemoteUser() {
00912                 // We don't use user authentification.
00913                 return null;
00914         }
00915 
00916         public RequestDispatcher getRequestDispatcher(String urlpath) {
00917                 // TODO: calculate dispacter relatively the current path
00918                 return null; // we don't provide resource dispatching in this way
00919         }
00920 
00921         public String getRequestedSessionId() {
00922                 // This WEB server only handles one session.
00923                 return this.getSession().getId();
00924         }
00925 
00926         public String getRequestURI() {
00927                 return reqUriPath;
00928         }
00929 
00930         public void setRequestURI(String uri) {
00931                 reqUriPath = uri;
00932         }
00933 
00934         public StringBuffer getRequestURL() {
00935                 return new StringBuffer().append(getScheme()).append("://").append(this.getServerName()).append(
00936                                 webserver.port == 80 ? "" : ":" + String.valueOf(webserver.port)).append(getRequestURI());
00937         }
00938 
00939         // / Returns the scheme of the URL used in this request, for example
00940         // "http", "https", or "ftp". Different schemes have different rules
00941         // for constructing URLs, as noted in RFC 1738. The URL used to create
00942         // a request may be reconstructed using this scheme, the server name
00943         // and port, and additional information such as URIs.
00944         public String getScheme() {
00945                 if (socket.getClass().getName().toUpperCase().indexOf("SSL") < 0)
00946                         return "http";
00947                 else
00948                         return "https";
00949         }
00950 
00951         // / Returns the host name of the server as used in the <host> part of
00952         // the request URI.
00953         // Same as the CGI variable SERVER_NAME.
00954         public String getServerName() {
00955                 String serverName;
00956                 serverName = getHeader("Host");
00957                 if (serverName != null && serverName.length() > 0) {
00958                         int colon = serverName.indexOf(':');
00959                         if (colon >= 0) {
00960                                 if (colon < serverName.length())
00961                                         serverName = serverName.substring(0, colon);
00962                         }
00963                 }
00964 
00965                 if (serverName == null) {
00966                         try {
00967                                 serverName = InetAddress.getLocalHost().getHostName();
00968                         } catch (java.net.UnknownHostException ignore) {
00969                                 serverName = "127.0.0.0";
00970                         }
00971                 }
00972 
00973                 int slash = serverName.indexOf("/");
00974                 if (slash >= 0)
00975                         serverName = serverName.substring(slash + 1);
00976                 return serverName;
00977         }
00978 
00979         // / Returns the port number on which this request was received as used in
00980         // the <port> part of the request URI.
00981         // Same as the CGI variable SERVER_PORT.
00982         public int getServerPort() {
00983                 return socket.getLocalPort();
00984         }
00985 
00986         public String getServletPath() {
00987                 // In this server, the entire path is regexp-matched against the
00988                 // servlet pattern, so there's no good way to distinguish which
00989                 // part refers to the servlet.
00990                 return uriLen > 0 ? reqUriPath.substring(0, uriLen) : "";
00991         }
00992 
00993         public HttpSession getSession() {
00994                 return this.getSession(true);
00995         }
00996 
00997         public HttpSession getSession(boolean create) {
00998                 // Only one seesion context
00999                 SessionContext session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
01000                 if (session == null) {
01001                         synchronized (SessionContextManager.getManager()) {
01002                                 session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
01003                                 if (session == null) {
01004                                         session = SessionContextManager.getManager().createSessionContext("OPENMOBILEISSESSION");
01005                                 }
01006                         }
01007                 }
01008                 SessionContextManager.getManager().joinSessionContext(session.getId());
01009                 return SessionContextManager.getManager().getSessionContext();
01010         }
01011 
01012         public Principal getUserPrincipal() {
01013                 // We don't use user authentification.
01014                 return null;
01015         }
01016 
01017         public boolean isRequestedSessionIdFromCookie() {
01018                 // We don't use cookies.
01019                 return false;
01020         }
01021 
01022         public boolean isRequestedSessionIdFromURL() {
01023                 // We only use on session for this web browser.
01024                 return false;
01025         }
01026 
01027         public boolean isRequestedSessionIdFromUrl() {
01028                 // We only use on session for this web browser.
01029                 return false;
01030         }
01031 
01032         public boolean isRequestedSessionIdValid() {
01033                 HttpSession session = this.getSession();
01034                 if (session != null) {
01035                         return true;
01036                 }
01037                 return false;
01038         }
01039 
01040         public boolean isSecure() {
01041                 return false;
01042         }
01043 
01044         public boolean isUserInRole(String arg0) {
01045                 // We don't use authentification.
01046                 return false;
01047         }
01048 
01049         public void removeAttribute(String name) {
01050                 attributes.remove(name);
01051         }
01052 
01053         public void setAttribute(String key, Object o) {
01054                 attributes.put(key, o);
01055         }
01056 
01068         public void setCharacterEncoding(String _enc) {
01069                 this.reqCharEncoding = _enc;
01070         }
01071 
01072         // HttpServletRequest AND HttpServletResponse METHODS
01073         // ***************************************************************************************************************
01074 
01075         // / Returns the character set encoding used for this MIME body. The
01076         // character encoding is either the one specified in the assigned
01077         // content type, or one which the client understands. If no content
01078         // type has yet been assigned, it is implicitly set to text/plain.
01079         public String getCharacterEncoding() {
01080                 String ct = (String) resHeaderNames.get(CONTENTTYPE);
01081                 if (ct != null) {
01082                         int scp = ct.indexOf(';');
01083                         if (scp > 0) {
01084                                 scp = ct.toLowerCase().indexOf("charset=", scp);
01085                                 if (scp >= 0) {
01086                                         ct = ct.substring(scp + 8);
01087                                         scp = ct.indexOf(' ');
01088                                         if (scp > 0)
01089                                                 ct = ct.substring(0, scp);
01090                                         scp = ct.indexOf(';');
01091                                         if (scp > 0)
01092                                                 ct = ct.substring(0, scp);
01093                                         return ct;
01094                                 }
01095                         }
01096                 }
01097                 return null;
01098         }
01099 
01100         public Locale getLocale() {
01101                 return locale;
01102         }
01103 
01104         // HttpServletResponse METHODS
01105         // ***************************************************************************************************************
01106 
01107         // / Adds the specified cookie to the response. It can be called
01108         // multiple times to set more than one cookie.
01109         public void addCookie(Cookie cookie) {
01110                 // We don't use cookies.
01111         }
01112 
01113         public void addDateHeader(String header, long date) {
01114                 addHeader(header, expdatefmt.format(new Date(date)));
01115         }
01116 
01117         public void addHeader(String header, String value) {
01118                 Object o = resHeaderNames.get(header);
01119                 if (o == null)
01120                         setHeader(header, value);
01121                 else {
01122                         if (o instanceof String[]) {
01123                                 String[] oldVal = (String[]) o;
01124                                 String[] newVal = new String[oldVal.length + 1];
01125                                 System.arraycopy(oldVal, 0, newVal, 0, oldVal.length);
01126                                 newVal[oldVal.length] = value;
01127                                 resHeaderNames.put(header, newVal);
01128                         } else if (o instanceof String) {
01129                                 String[] newVal = new String[2];
01130                                 newVal[0] = (String) o;
01131                                 newVal[1] = value;
01132                                 resHeaderNames.put(header, newVal);
01133                         } else
01134                                 throw new RuntimeException("Invalid content of header hash - " + o.getClass().getName());
01135                 }
01136         }
01137 
01138         public void addIntHeader(String header, int value) {
01139                 addHeader(header, Integer.toString(value));
01140         }
01141 
01142         // / Checks whether the response message header has a field with the
01143         // specified name.
01144         public boolean containsHeader(String name) {
01145                 return resHeaderNames.contains(name);
01146         }
01147 
01148         // / Encodes the specified URL for use in the sendRedirect method or, if
01149         // encoding is not needed, returns the URL unchanged. The
01150         // implementation of this method should include the logic to determine
01151         // whether the session ID needs to be encoded in the URL. Because the
01152         // rules for making this determination differ from those used to
01153         // decide whether to encode a normal link, this method is seperate
01154         // from the encodeUrl method.
01155         // <P>
01156         // All URLs sent to the HttpServletResponse.sendRedirect method should be
01157         // run through this method. Otherwise, URL rewriting cannot be used with
01158         // browsers which do not support cookies.
01159         public String encodeRedirectUrl(String url) {
01160                 return url;
01161         }
01162 
01163         public String encodeRedirectURL(String url) {
01164                 return url; // as is
01165         }
01166 
01167         // URL session-encoding stuff. Not implemented, but the API is here
01168         // for compatibility.
01169 
01170         // / Encodes the specified URL by including the session ID in it, or, if
01171         // encoding is not needed, returns the URL unchanged. The
01172         // implementation of this method should include the logic to determine
01173         // whether the session ID needs to be encoded in the URL. For example,
01174         // if the browser supports cookies, or session tracking is turned off,
01175         // URL encoding is unnecessary.
01176         // <P>
01177         // All URLs emitted by a Servlet should be run through this method.
01178         // Otherwise, URL rewriting cannot be used with browsers which do not
01179         // support cookies.
01180         public String encodeUrl(String url) {
01181                 return url;
01182         }
01183 
01184         // JSDK 2.1 extension
01185         public String encodeURL(String url) {
01186                 return url; // as is
01187         }
01188 
01189         // 2.2
01190         // do not use buffer
01191         public void flushBuffer() {
01192         }
01193 
01194         public int getBufferSize() {
01195                 return 0;
01196         }
01197 
01198         // / Returns an output stream for writing response data.
01199         public ServletOutputStream getOutputStream() throws IOException {
01200                 synchronized (out) {
01201                         if (((ServeOutputStream) out).isReturnedAsWriter())
01202                                 throw new IllegalStateException("Already returned as a writer");
01203                         ((ServeOutputStream) out).setReturnedAsStream(true);
01204                 }
01205                 return out;
01206         }
01207 
01208         // / Returns a print writer for writing response data. The MIME type of
01209         // the response will be modified, if necessary, to reflect the character
01210         // encoding used, through the charset=... property. This means that the
01211         // content type must be set before calling this method.
01212         // @exception UnsupportedEncodingException if no such encoding can be provided
01213         // @exception IllegalStateException if getOutputStream has been called
01214         // @exception IOException on other I/O errors
01215         public PrintWriter getWriter() throws IOException {
01216                 synchronized (out) {
01217                         if (((ServeOutputStream) out).isReturnedAsStream())
01218                                 throw new IllegalStateException("Already was returned as servlet output stream");
01219                         ((ServeOutputStream) out).setReturnedAsWriter(true);
01220                 }
01221                 String encoding = getCharacterEncoding();
01222                 if (encoding != null) {
01223                         // return new PrintWriter(new OutputStreamWriter(out, encoding));
01224                         printWriter = new PrintWriter(new OutputStreamWriter(out, encoding));
01225                 } else {
01226                         // return new PrintWriter(out);
01227                         printWriter = new PrintWriter(out);
01228                 }
01229                 return printWriter;
01230         }
01231 
01239         // a caller should think about syncronization
01240         public boolean isCommitted() {
01241                 return headersWritten;
01242         }
01243 
01253         public void reset() {
01254                 if (!isCommitted()) {
01255                         resHeaderNames.clear();
01256                 } else
01257                         throw new IllegalStateException("Header have already been committed.");
01258         }
01259 
01260         public void resetBuffer() {
01261                 throw new IllegalStateException("The method not implemented");
01262         }
01263 
01264         // / Writes an error response using the specified status code and message.
01265         // @param resCode the status code
01266         // @param resMessage the status message
01267         // @exception IOException if an I/O error has occurred
01268         public void sendError(int resCode, String resMessage) throws IOException {
01269                 setStatus(resCode, resMessage);
01270                 realSendError();
01271         }
01272 
01273         // / Writes an error response using the specified status code and a default
01274         // message.
01275         // @param resCode the status code
01276         // @exception IOException if an I/O error has occurred
01277         public void sendError(int resCode) throws IOException {
01278                 setStatus(resCode);
01279                 realSendError();
01280         }
01281 
01282         // / Sends a redirect message to the client using the specified redirect
01283         // location URL.
01284         // @param location the redirect location URL
01285         // @exception IOException if an I/O error has occurred
01286         public void sendRedirect(String location) throws IOException {
01287                 if (isCommitted())
01288                         throw new IllegalStateException("Can not redirect, headers have been already written");
01289                 synchronized (out) {
01290                         // no more out after redirect
01291                         ((ServeOutputStream) out).setReturnedAsStream(true);
01292                         ((ServeOutputStream) out).setReturnedAsWriter(true);
01293                 }
01294                 setHeader("Location", location);
01295                 setStatus(SC_MOVED_TEMPORARILY);
01296                 setContentType("text/html");
01297                 StringBuffer sb = new StringBuffer(200);
01298                 sb.append("<HTML><HEAD>" + "<TITLE>" + SC_MOVED_TEMPORARILY + " Moved</TITLE>" + "</HEAD><BODY BGCOLOR=\"#F1D0F2\">" + "<H2>" + SC_MOVED_TEMPORARILY
01299                                 + " Moved</H2>" + "This document has moved <a href=" + location + ">here.<HR>");
01300                 Identification.writeAddress(sb);
01301                 sb.append("</BODY></HTML>");
01302                 setContentLength(sb.length());
01303                 // to avoid further out
01304                 out.print(sb.toString());
01305                 out.flush();
01306         }
01307 
01308         // 2.2
01309         // do not use buffer
01310         public void setBufferSize(int size) {
01311         }
01312 
01313         // / Sets the content length for this response.
01314         // @param length the content length
01315         public void setContentLength(int length) {
01316                 setIntHeader(CONTENTLENGTH, length);
01317         }
01318 
01319         // / Sets the content type for this response.
01320         // @param type the content type
01321         public void setContentType(String type) {
01322                 setHeader(CONTENTTYPE, type != null ? type : "Unknown");
01323         }
01324 
01325         // / Sets the value of a date header field.
01326         // @param name the header field name
01327         // @param value the header field date value
01328         public void setDateHeader(String name, long value) {
01329                 setHeader(name, expdatefmt.format(new Date(value)));
01330         }
01331 
01332         // / Sets the value of a header field.
01333         // @param name the header field name
01334         // @param value the header field value
01335         public void setHeader(String name, String value) {
01336                 resHeaderNames.put(name, value);
01337         }
01338 
01339         // / Sets the value of an integer header field.
01340         // @param name the header field name
01341         // @param value the header field integer value
01342         public void setIntHeader(String name, int value) {
01343                 setHeader(name, Integer.toString(value));
01344         }
01345 
01356         public void setLocale(Locale locale) {
01357                 this.locale = locale;
01358         }
01359 
01360         // / Sets the status code and a default message for this response.
01361         // @param resCode the status code
01362         public void setStatus(int resCode) {
01363                 switch (resCode) {
01364                 case SC_CONTINUE:
01365                         setStatus(resCode, "Continue");
01366                         break;
01367                 case SC_SWITCHING_PROTOCOLS:
01368                         setStatus(resCode, "Switching protocols");
01369                         break;
01370                 case SC_OK:
01371                         setStatus(resCode, "Ok");
01372                         break;
01373                 case SC_CREATED:
01374                         setStatus(resCode, "Created");
01375                         break;
01376                 case SC_ACCEPTED:
01377                         setStatus(resCode, "Accepted");
01378                         break;
01379                 case SC_NON_AUTHORITATIVE_INFORMATION:
01380                         setStatus(resCode, "Non-authoritative");
01381                         break;
01382                 case SC_NO_CONTENT:
01383                         setStatus(resCode, "No content");
01384                         break;
01385                 case SC_RESET_CONTENT:
01386                         setStatus(resCode, "Reset content");
01387                         break;
01388                 case SC_PARTIAL_CONTENT:
01389                         setStatus(resCode, "Partial content");
01390                         break;
01391                 case SC_MULTIPLE_CHOICES:
01392                         setStatus(resCode, "Multiple choices");
01393                         break;
01394                 case SC_MOVED_PERMANENTLY:
01395                         setStatus(resCode, "Moved permanentently");
01396                         break;
01397                 case SC_MOVED_TEMPORARILY:
01398                         setStatus(resCode, "Moved temporarily");
01399                         break;
01400                 case SC_SEE_OTHER:
01401                         setStatus(resCode, "See other");
01402                         break;
01403                 case SC_NOT_MODIFIED:
01404                         setStatus(resCode, "Not modified");
01405                         break;
01406                 case SC_USE_PROXY:
01407                         setStatus(resCode, "Use proxy");
01408                         break;
01409                 case SC_BAD_REQUEST:
01410                         setStatus(resCode, "Bad request");
01411                         break;
01412                 case SC_UNAUTHORIZED:
01413                         setStatus(resCode, "Unauthorized");
01414                         break;
01415                 case SC_PAYMENT_REQUIRED:
01416                         setStatus(resCode, "Payment required");
01417                         break;
01418                 case SC_FORBIDDEN:
01419                         setStatus(resCode, "Forbidden");
01420                         break;
01421                 case SC_NOT_FOUND:
01422                         setStatus(resCode, "Not found");
01423                         break;
01424                 case SC_METHOD_NOT_ALLOWED:
01425                         setStatus(resCode, "Method not allowed");
01426                         break;
01427                 case SC_NOT_ACCEPTABLE:
01428                         setStatus(resCode, "Not acceptable");
01429                         break;
01430                 case SC_PROXY_AUTHENTICATION_REQUIRED:
01431                         setStatus(resCode, "Proxy auth required");
01432                         break;
01433                 case SC_REQUEST_TIMEOUT:
01434                         setStatus(resCode, "Request timeout");
01435                         break;
01436                 case SC_CONFLICT:
01437                         setStatus(resCode, "Conflict");
01438                         break;
01439                 case SC_GONE:
01440                         setStatus(resCode, "Gone");
01441                         break;
01442                 case SC_LENGTH_REQUIRED:
01443                         setStatus(resCode, "Length required");
01444                         break;
01445                 case SC_PRECONDITION_FAILED:
01446                         setStatus(resCode, "Precondition failed");
01447                         break;
01448                 case SC_REQUEST_ENTITY_TOO_LARGE:
01449                         setStatus(resCode, "Request entity too large");
01450                         break;
01451                 case SC_REQUEST_URI_TOO_LONG:
01452                         setStatus(resCode, "Request URI too large");
01453                         break;
01454                 case SC_UNSUPPORTED_MEDIA_TYPE:
01455                         setStatus(resCode, "Unsupported media type");
01456                         break;
01457                 case SC_INTERNAL_SERVER_ERROR:
01458                         setStatus(resCode, "Internal server error");
01459                         break;
01460                 case SC_NOT_IMPLEMENTED:
01461                         setStatus(resCode, "Not implemented");
01462                         break;
01463                 case SC_BAD_GATEWAY:
01464                         setStatus(resCode, "Bad gateway");
01465                         break;
01466                 case SC_SERVICE_UNAVAILABLE:
01467                         setStatus(resCode, "Service unavailable");
01468                         break;
01469                 case SC_GATEWAY_TIMEOUT:
01470                         setStatus(resCode, "Gateway timeout");
01471                         break;
01472                 case SC_HTTP_VERSION_NOT_SUPPORTED:
01473                         setStatus(resCode, "HTTP version not supported");
01474                         break;
01475                 default:
01476                         setStatus(resCode, "");
01477                         break;
01478                 }
01479         }
01480 
01481         // / Sets the status code and message for this response.
01482         // @param resCode the status code
01483         // @param resMessage the status message
01484         public void setStatus(int resCode, String resMessage) {
01485                 // if (this.resCode > 0 && this.resCode != SC_OK)
01486                 // throw new IllegalStateException("Result code "+this.resCode+" was
01487                 // already set.");
01488                 this.resCode = resCode;
01489                 this.resMessage = resMessage;
01490         }
01491 
01492 }

Generated on Mon Jan 11 21:19:17 2010 for OpenMobileIS by  doxygen 1.5.4