00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 package org.openmobileis.embedded.webserver;
00031
00032 import java.io.BufferedReader;
00033 import java.io.IOException;
00034 import java.io.InputStreamReader;
00035 import java.io.OutputStreamWriter;
00036 import java.io.PrintWriter;
00037 import java.io.UnsupportedEncodingException;
00038 import java.net.InetAddress;
00039 import java.net.Socket;
00040 import java.security.Principal;
00041 import java.text.SimpleDateFormat;
00042 import java.util.Date;
00043 import java.util.Enumeration;
00044 import java.util.Hashtable;
00045 import java.util.Locale;
00046 import java.util.StringTokenizer;
00047 import java.util.Vector;
00048
00049 import javax.servlet.RequestDispatcher;
00050 import javax.servlet.ServletException;
00051 import javax.servlet.ServletInputStream;
00052 import javax.servlet.ServletOutputStream;
00053 import javax.servlet.ServletRequest;
00054 import javax.servlet.ServletResponse;
00055 import javax.servlet.SingleThreadModel;
00056 import javax.servlet.http.Cookie;
00057 import javax.servlet.http.HttpServlet;
00058 import javax.servlet.http.HttpServletRequest;
00059 import javax.servlet.http.HttpServletResponse;
00060 import javax.servlet.http.HttpSession;
00061 import javax.servlet.http.HttpUtils;
00062
00063 import org.openmobileis.common.context.SessionContext;
00064 import org.openmobileis.common.context.SessionContextManager;
00065 import org.openmobileis.common.util.log.LogManager;
00066 import org.openmobileis.common.util.log.LogServices;
00067
00068
00069 public class WebServerConnection implements HttpServletRequest, HttpServletResponse {
00070
00071 public final static String WWWFORMURLENCODE = "application/x-www-form-urlencoded";
00072 public final static String TRANSFERENCODING = "Transfer-Encoding";
00073 public final static String CHUNKED = "chunked";
00074 public final static String CONTENTLENGTH = "Content-Length";
00075 public final static String CONTENTTYPE = "Content-Type";
00076
00077 private Socket socket;
00078 private WebServer webserver;
00079
00080 private String reqMethod;
00081
00082 private String reqUriPath;
00083
00084 private boolean oneOne;
00085
00086 String reqQuery = null;
00087
00088 private Vector reqHeaderNames = new Vector();
00089 private Vector reqHeaderValues = new Vector();
00090 private Locale locale;
00091
00092 private int uriLen;
00093 private static final Hashtable EMPTYHASHTABLE = new Hashtable();
00094
00095 protected long connexionLifeTime = 0;
00096
00097 private ServletInputStream in;
00098
00099 private ServletOutputStream out;
00100
00101 private boolean reqMime;
00102
00103 private String reqProtocol;
00104 private String reqCharEncoding;
00105
00106 private Hashtable formParameters;
00107
00108 private Hashtable attributes = new Hashtable();
00109
00110 private int resCode = -1;
00111
00112 private String resMessage = null;
00113
00114 private Hashtable resHeaderNames = new Hashtable();
00115
00116 private boolean headersWritten = false;
00117
00118 protected static final SimpleDateFormat expdatefmt = new SimpleDateFormat(
00119 "EEE, dd-MMM-yyyy HH:mm:ss 'GMT'");
00120
00121 protected static final SimpleDateFormat headerdateformat = new SimpleDateFormat(
00122 "EEE, dd MMM yyyy HH:mm:ss z");
00123
00124 private PrintWriter printWriter = null;
00125
00126 public void init(WebServer webserver, Socket socket) {
00127
00128 this.webserver = webserver;
00129 this.socket = socket;
00130 out = null;
00131 in = null;
00132 oneOne = false;
00133 reqMethod = null;
00134 reqUriPath = null;
00135 reqQuery = null;
00136 reqProtocol = null;
00137 reqCharEncoding = null;
00138 reqHeaderNames = new Vector();
00139 reqHeaderValues = new Vector();
00140 formParameters = null;
00141 attributes = new Hashtable();
00142 locale = null;
00143 uriLen = -1;
00144 resCode = -1;
00145 connexionLifeTime = 0;
00146 reqMime = false;
00147 resMessage = "";
00148 resHeaderNames = new Hashtable();
00149 headersWritten = false;
00150 printWriter = null;
00151 }
00152
00153
00154 public void run() {
00155 SessionContextManager.getManager().joinSessionContext("OPENMOBILEISSESSION");
00156 try {
00157
00158 in = new ServeInputStream(socket.getInputStream());
00159 out = new ServeOutputStream(socket.getOutputStream(), this);
00160 } catch (IOException e) {
00161 problem("Getting streams: " + e.getMessage(), SC_BAD_REQUEST);
00162 LogManager.traceError(0, e);
00163 try {
00164 socket.close();
00165 } catch (Exception ex){}
00166 return;
00167 }
00168
00169
00170 parseRequest();
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 try {
00181 this.execURI(this.reqUriPath);
00182 } catch (Exception e) {
00183 problem("Getting streams: " + e.getMessage(), SC_BAD_REQUEST);
00184 LogManager.traceError(0, e);
00185 } finally {
00186 try {
00187
00188 socket.close();
00189 } catch (IOException e) {
00190 org.openmobileis.common.util.log.LogManager
00191 .traceError(
00192 org.openmobileis.common.util.log.LogServices.WEBSERVICE,
00193 "Impossible to close socket : WebServerConnection");
00194 org.openmobileis.common.util.log.LogManager
00195 .traceError(
00196 org.openmobileis.common.util.log.LogServices.WEBSERVICE,
00197 e);
00198 }
00199 }
00200 }
00201
00202 private void parseRequest() {
00203 byte[] lineBytes = new byte[4096];
00204 int len;
00205 String line;
00206
00207 try {
00208
00209 len = in.readLine(lineBytes, 0, lineBytes.length);
00210 if (len == -1 || len == 0) {
00211 problem("Empty request", SC_BAD_REQUEST);
00212 return;
00213 }
00214 line = new String(lineBytes, 0, len);
00215 StringTokenizer ust = new StringTokenizer(line);
00216 reqProtocol = null;
00217 if (ust.hasMoreTokens()) {
00218 reqMethod = ust.nextToken();
00219 if (ust.hasMoreTokens()) {
00220 reqUriPath = Acme.Utils.urlDecoder(ust.nextToken());
00221 if (ust.hasMoreTokens()) {
00222 reqProtocol = ust.nextToken();
00223 oneOne = !reqProtocol.toUpperCase().equals("HTTP/1.0");
00224 reqMime = true;
00225
00226 String s;
00227 while ((s = ((ServeInputStream) in).readLine()) != null) {
00228 if (s.length() == 0)
00229 break;
00230
00231 int c = s.indexOf(':', 0);
00232 if (c > 0) {
00233 String key = s.substring(0, c).trim();
00234 String value = s.substring(c + 1, s.length())
00235 .trim();
00236 reqHeaderNames.addElement(key.toLowerCase());
00237 reqHeaderValues.addElement(value);
00238 } else {
00239 LogManager.traceError(LogServices.WEBSERVICE, "header field without ':'");
00240 }
00241 }
00242 } else {
00243 reqProtocol = "HTTP/0.9";
00244 oneOne = false;
00245 reqMime = false;
00246 }
00247 }
00248 }
00249 if (reqProtocol == null) {
00250 problem("Malformed request line", SC_BAD_REQUEST);
00251 return;
00252 }
00253
00254 if (oneOne) {
00255 String host = getHeader("host");
00256 if (host == null) {
00257 problem("Host header missing on HTTP/1.1 request",
00258 SC_BAD_REQUEST);
00259 return;
00260 }
00261 }
00262
00263
00264
00265
00266 int qmark = reqUriPath.indexOf('?');
00267 if (qmark > -1) {
00268 reqQuery = reqUriPath.substring(qmark + 1);
00269 reqUriPath = reqUriPath.substring(0, qmark);
00270 }
00271 if (CHUNKED.equals(getHeader(TRANSFERENCODING))) {
00272 setHeader(CONTENTLENGTH, null);
00273 ((ServeInputStream) in).chunking(true);
00274 }
00275
00276 } catch (IOException e) {
00277 problem("Reading request: " + e.getMessage(), SC_BAD_REQUEST);
00278 }
00279 }
00280
00281 private void execURI(String URI) throws ServletException {
00282
00283 if (URI.equals("/index")) {
00284 URI = "/services/index";
00285 reqUriPath = URI;
00286 }
00287 Object[] os = webserver.getServletByURLorClassName(URI);
00288 if (os[0] == null) {
00289 os = webserver.getServletByURLorClassName("defaultServlet");
00290 if (os[0] == null) {
00291 throw new ServletException(
00292 "WebServerConnection::execUri Unable to find file servlet");
00293 }
00294
00295 uriLen = 0;
00296 runServlet((HttpServlet) os[0]);
00297 } else {
00298 uriLen = ((Integer) os[1]).intValue();
00299 runServlet((HttpServlet) os[0]);
00300 }
00301 }
00302
00304
00305
00306 void writeHeaders() throws IOException {
00307 synchronized (this) {
00308 if (headersWritten)
00309 return;
00310
00311 headersWritten = true;
00312 }
00313 if (reqMime) {
00314
00315 out.println(reqProtocol + " " + resCode + " " + resMessage);
00316
00317 Enumeration he = resHeaderNames.keys();
00318 while (he.hasMoreElements()) {
00319 String name = (String) he.nextElement();
00320 Object o = resHeaderNames.get(name);
00321 if (o instanceof String) {
00322 String value = (String) o;
00323 if (value != null)
00324 out.println(name + ": " + value);
00325
00326
00327
00328
00329 } else if (o instanceof String[]) {
00330 String[] values = (String[]) o;
00331 out.println(name + ": " + values[0]);
00332 for (int i = 0; i < values.length; i++)
00333 out.print("," + values[i]);
00334 out.println();
00335 }
00336 }
00337
00338 out.println("Pragma: no-cache");
00339 out.println("Cache-Control: no-cache, must-revalidate");
00340 out.println("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
00341 out.println("Date: Mon, 26 Jul 1997 05:00:00 GMT");
00342
00343 out.println("Last-Modified: Mon, 26 Jul 1997 05:00:00 GMT");
00344 out.println("Connection: close" );
00345
00346 out.println();
00347 out.flush();
00348
00349 }
00350 }
00351
00352 private void runServlet(HttpServlet servlete) {
00353
00354 setStatus(SC_OK);
00355
00356
00357
00358
00359
00360
00361 try {
00362 authenticate();
00363 ((SessionContext)this.getSession()).setServletContext(servlete.getServletConfig().getServletContext());
00364 if (servlete instanceof SingleThreadModel)
00365 synchronized (servlete) {
00366 servlete.service((ServletRequest) this,
00367 (ServletResponse) this);
00368 }
00369 else {
00370 servlete.service((ServletRequest) this, (ServletResponse) this);
00371 }
00372 if (((ServeOutputStream)out).isReturnedAsWriter() && printWriter != null) {
00373 printWriter.flush();
00374 } else {
00375 out.flush();
00376 }
00377 } catch (IOException e) {
00378 e.printStackTrace();
00379 problem("IO problem running servlet: " + e.toString(),
00380 SC_BAD_REQUEST);
00381 } catch (ServletException e) {
00382 e.printStackTrace();
00383 problem("problem running servlet: " + e.toString(), SC_BAD_REQUEST);
00384 } catch (Exception e) {
00385 e.printStackTrace();
00386 problem("unexpected problem running servlet: " + e.toString(),
00387 SC_INTERNAL_SERVER_ERROR);
00388 }
00389 }
00390
00391 private boolean authenticate() throws IOException {
00392
00393 return true;
00394 }
00395
00396
00397 private void problem(String logMessage, int resCode) {
00398 LogManager.traceError(LogServices.WEBSERVICE, logMessage);
00399 try {
00400 sendError(resCode);
00401 } catch (IllegalStateException e) {
00402 } catch (IOException e) {
00403 }
00404 }
00405
00406 private Hashtable getParametersFromRequest() {
00407 Hashtable result = null;
00408
00409
00410 if ("GET".equals(reqMethod)) {
00411 if (reqQuery != null)
00412 try {
00413 result = HttpUtils.parseQueryString(reqQuery);
00414 } catch (IllegalArgumentException ex) {
00415 }
00416 } else if ("POST".equals(reqMethod))
00417 if (WWWFORMURLENCODE.equals(getContentType()))
00418 try {
00419 result = HttpUtils.parsePostData(getContentLength(), getInputStream());
00420 if (reqQuery != null && reqQuery.length() > 0) {
00421 Acme.Utils.putAll(result, HttpUtils.parseQueryString(reqQuery));
00422 }
00423 } catch (Exception ex) {
00424 LogManager.traceError(0, ex);
00425 LogManager.traceError(LogServices.WEBSERVICE, "Exception " + ex + " at parsing post data of length " + getContentLength());
00426 }
00427 else
00428 try {
00429 if (reqQuery != null)
00430 result = HttpUtils.parseQueryString(reqQuery);
00431 } catch (Exception ex) {
00432 }
00433 return result != null ? result : EMPTYHASHTABLE;
00434 }
00435
00436 private void realSendError() throws IOException {
00437 if (isCommitted())
00438 throw new IllegalStateException(
00439 "Can not send error, headers have been already written");
00440 synchronized (out) {
00441
00442 ((ServeOutputStream) out).setReturnedAsStream(true);
00443 ((ServeOutputStream) out).setReturnedAsWriter(true);
00444 }
00445 setContentType("text/html");
00446 StringBuffer sb = new StringBuffer(100);
00447 sb.append("<HTML><HEAD>").append(
00448 "<TITLE>" + resCode + " " + resMessage + "</TITLE>").append(
00449 "</HEAD><BODY BGCOLOR=\"#F1D0F2\">").append(
00450 "<H2>" + resCode + " " + resMessage + "</H2>").append("<HR>");
00451 Identification.writeAddress(sb);
00452 sb.append("</BODY></HTML>");
00453 setContentLength(sb.length());
00454 out.print(sb.toString());
00455 out.flush();
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00483
00484
00485 public Object getAttribute(String name) {
00486 return attributes.get(name);
00487 }
00488
00489
00490 public Enumeration getAttributeNames() {
00491 return attributes.keys();
00492 }
00493
00494 public String getAuthType() {
00495
00496 return null;
00497 }
00498
00500
00501 public int getContentLength() {
00502 try {
00503 return this.getIntHeader(CONTENTLENGTH);
00504 } catch (Exception ex) {
00505 return -1;
00506 }
00507 }
00508
00510
00511
00512 public String getContentType() {
00513 return getHeader(CONTENTTYPE);
00514 }
00515
00516 public String getContextPath() {
00517 return "";
00518 }
00519
00520 public Cookie[] getCookies() {
00521
00522 return null;
00523 }
00524
00525 public long getDateHeader(String name) {
00526 String val = getHeader(name);
00527 if (val == null)
00528 return 0;
00529 try {
00530 return headerdateformat.parse(val).getTime();
00531 } catch (Exception e) {
00532 throw new IllegalArgumentException("Value " + val
00533 + " can't be converted to Date using "
00534 + headerdateformat.toPattern());
00535 }
00536 }
00537
00538 public String getHeader(String name) {
00539 int i = reqHeaderNames.indexOf(name.toLowerCase());
00540 if (i == -1)
00541 return null;
00542 return (String) reqHeaderValues.elementAt(i);
00543 }
00544
00545 public Enumeration getHeaderNames() {
00546 return reqHeaderNames.elements();
00547 }
00548
00549 public Enumeration getHeaders(String header) {
00550 Vector result = new Vector();
00551 int i = -1;
00552 while ((i = reqHeaderNames.indexOf(header.toLowerCase(), i + 1)) >= 0)
00553 result.addElement(reqHeaderValues.elementAt(i));
00554 return result.elements();
00555 }
00556
00558
00559
00560 public ServletInputStream getInputStream() throws IOException {
00561 synchronized (in) {
00562 if (((ServeInputStream) in).isReturnedAsReader())
00563 throw new IllegalStateException("Already returned as a reader.");
00564 ((ServeInputStream) in).setReturnedAsReader(true);
00565 }
00566 return in;
00567 }
00568
00570
00571 public int getIntHeader(String name) {
00572 String val = getHeader(name);
00573 if (val == null)
00574 return -1;
00575
00576
00577
00578
00579 return Integer.parseInt(val);
00580 }
00581
00592 public String getLocalAddr() {
00593 return null;
00594 }
00595
00596
00597 public Enumeration getLocales() {
00598
00599
00600 return null;
00601 }
00602
00612 public String getLocalName() {
00613 return null;
00614 }
00615
00624 public int getLocalPort() {
00625 return webserver.port;
00626 }
00627
00628 public String getMethod() {
00629 return reqMethod;
00630 }
00631
00633
00634
00635 public String getParameter(String name) {
00636 String[] params = getParameterValues(name);
00637 if (params == null || params.length == 0)
00638 return null;
00639
00640 return params[0];
00641 }
00642
00652 public java.util.Map getParameterMap() {
00653 return (java.util.Map) formParameters;
00654 }
00655
00657 public Enumeration getParameterNames() {
00658 if (formParameters == null)
00659 formParameters = getParametersFromRequest();
00660 return formParameters.keys();
00661 }
00662
00664
00665 public String[] getParameterValues(String name) {
00666 if (formParameters == null)
00667 getParameterNames();
00668
00669 return (String[]) formParameters.get(name);
00670 }
00671
00672 public String getPathInfo() {
00673
00674
00675
00676 return uriLen >= reqUriPath.length() ? null : reqUriPath.substring(uriLen);
00677 }
00678
00679 public String getPathTranslated() {
00680
00681
00682
00683 return getRealPath(getPathInfo());
00684 }
00685
00687
00688
00689 public String getProtocol() {
00690 return reqProtocol;
00691 }
00692
00693
00694
00695 public String getQueryString() {
00696 return reqQuery;
00697 }
00698
00700
00701
00702
00703 public BufferedReader getReader() throws IOException {
00704 synchronized (in) {
00705 if (((ServeInputStream) in).isReturnedAsStream())
00706 throw new IllegalStateException("Already returned as a stream.");
00707 ((ServeInputStream) in).setReturnedAsStream(true);
00708 }
00709 if (reqCharEncoding != null)
00710 try {
00711 return new BufferedReader(new InputStreamReader(in, reqCharEncoding));
00712 } catch (UnsupportedEncodingException uee) {
00713 }
00714 return new BufferedReader(new InputStreamReader(in));
00715 }
00716
00718
00719
00720
00721
00722
00723 public String getRealPath(String path) {
00724 return webserver.getRealPath(path);
00725 }
00726
00728
00729 public String getRemoteAddr() {
00730 return socket.getInetAddress().getHostAddress().toString();
00731 }
00732
00734
00735
00736 public String getRemoteHost() {
00737 String result = socket.getInetAddress().getHostName();
00738 return result != null ? result : getRemoteAddr();
00739 }
00740
00749 public int getRemotePort() {
00750
00751 return webserver.port;
00752 }
00753
00755
00756 public String getRemoteUser() {
00757
00758 return null;
00759 }
00760
00761 public RequestDispatcher getRequestDispatcher(String urlpath) {
00762
00763 return null;
00764 }
00765
00766 public String getRequestedSessionId() {
00767
00768 return this.getSession().getId();
00769 }
00770
00771 public String getRequestURI() {
00772 return reqUriPath;
00773 }
00774
00775 public void setRequestURI(String uri) {
00776 reqUriPath = uri;
00777 }
00778
00779 public StringBuffer getRequestURL() {
00780 return new StringBuffer().append(getScheme()).append("://").append(this.getServerName())
00781 .append(webserver.port == 80 ? "" : ":"+String.valueOf(webserver.port)).append(getRequestURI());
00782 }
00783
00785
00786
00787
00788
00789 public String getScheme() {
00790 if (socket.getClass().getName().toUpperCase().indexOf("SSL") < 0)
00791 return "http";
00792 else
00793 return "https";
00794 }
00795
00797
00798
00799 public String getServerName() {
00800 String serverName;
00801 serverName = getHeader("Host");
00802 if (serverName != null && serverName.length() > 0) {
00803 int colon = serverName.indexOf(':');
00804 if (colon >= 0) {
00805 if (colon < serverName.length()) serverName = serverName.substring(0, colon);
00806 }
00807 }
00808
00809 if (serverName == null) {
00810 try {
00811 serverName = InetAddress.getLocalHost().getHostName();
00812 } catch (java.net.UnknownHostException ignore) {
00813 serverName = "127.0.0.0";
00814 }
00815 }
00816
00817 int slash = serverName.indexOf("/");
00818 if (slash >= 0)
00819 serverName = serverName.substring(slash + 1);
00820 return serverName;
00821 }
00822
00824
00825
00826 public int getServerPort() {
00827 return socket.getLocalPort();
00828 }
00829
00830 public String getServletPath() {
00831
00832
00833
00834 return uriLen > 0 ? reqUriPath.substring(0, uriLen) : "";
00835 }
00836
00837 public HttpSession getSession() {
00838 return this.getSession(true);
00839 }
00840
00841 public HttpSession getSession(boolean create) {
00842
00843 SessionContext session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00844 if (session == null) {
00845 synchronized (SessionContextManager.getManager()) {
00846 session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00847 if (session == null) {
00848 session = SessionContextManager.getManager().createSessionContext("OPENMOBILEISSESSION");
00849 }
00850 }
00851 }
00852 SessionContextManager.getManager().joinSessionContext(session.getId());
00853 return SessionContextManager.getManager().getSessionContext();
00854 }
00855
00856 public Principal getUserPrincipal() {
00857
00858 return null;
00859 }
00860
00861 public boolean isRequestedSessionIdFromCookie() {
00862
00863 return false;
00864 }
00865
00866 public boolean isRequestedSessionIdFromURL() {
00867
00868 return false;
00869 }
00870
00871 public boolean isRequestedSessionIdFromUrl() {
00872
00873 return false;
00874 }
00875
00876 public boolean isRequestedSessionIdValid() {
00877 HttpSession session = this.getSession();
00878 if (session != null) {
00879 return true;
00880 }
00881 return false;
00882 }
00883
00884 public boolean isSecure() {
00885 return false;
00886 }
00887
00888 public boolean isUserInRole(String arg0) {
00889
00890 return false;
00891 }
00892
00893 public void removeAttribute(String name) {
00894 attributes.remove(name);
00895 }
00896
00897 public void setAttribute(String key, Object o) {
00898 attributes.put(key, o);
00899 }
00900
00908 public void setCharacterEncoding(String _enc) {
00909 reqCharEncoding = _enc;
00910 }
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00930
00931
00932
00933 public String getCharacterEncoding() {
00934 String ct = (String) resHeaderNames.get(CONTENTTYPE);
00935 if (ct != null) {
00936 int scp = ct.indexOf(';');
00937 if (scp > 0) {
00938 scp = ct.toLowerCase().indexOf("charset=", scp);
00939 if (scp >= 0) {
00940 ct = ct.substring(scp + 8);
00941 scp = ct.indexOf(' ');
00942 if (scp > 0)
00943 ct = ct.substring(0, scp);
00944 scp = ct.indexOf(';');
00945 if (scp > 0)
00946 ct = ct.substring(0, scp);
00947 return ct;
00948 }
00949 }
00950 }
00951 return null;
00952 }
00953
00954 public Locale getLocale() {
00955 return locale;
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00990
00991 public void addCookie(Cookie cookie) {
00992
00993 }
00994
00995 public void addDateHeader(String header, long date) {
00996 addHeader(header, expdatefmt.format(new Date(date)));
00997 }
00998
00999 public void addHeader(String header, String value) {
01000 Object o = resHeaderNames.get(header);
01001 if (o == null)
01002 setHeader(header, value);
01003 else {
01004 if (o instanceof String[]) {
01005 String[] oldVal = (String[]) o;
01006 String[] newVal = new String[oldVal.length + 1];
01007 System.arraycopy(oldVal, 0, newVal, 0, oldVal.length);
01008 newVal[oldVal.length] = value;
01009 resHeaderNames.put(header, newVal);
01010 } else if (o instanceof String) {
01011 String[] newVal = new String[2];
01012 newVal[0] = (String) o;
01013 newVal[1] = value;
01014 resHeaderNames.put(header, newVal);
01015 } else
01016 throw new RuntimeException("Invalid content of header hash - "
01017 + o.getClass().getName());
01018 }
01019 }
01020
01021 public void addIntHeader(String header, int value) {
01022 addHeader(header, Integer.toString(value));
01023 }
01024
01026
01027 public boolean containsHeader(String name) {
01028 return resHeaderNames.contains(name);
01029 }
01030
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 public String encodeRedirectUrl(String url) {
01043 return url;
01044 }
01045
01046 public String encodeRedirectURL(String url) {
01047 return url;
01048 }
01049
01050
01051
01052
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 public String encodeUrl(String url) {
01064 return url;
01065 }
01066
01067
01068 public String encodeURL(String url) {
01069 return url;
01070 }
01071
01072
01073
01074 public void flushBuffer() {
01075 }
01076
01077 public int getBufferSize() {
01078 return 0;
01079 }
01080
01082 public ServletOutputStream getOutputStream() throws IOException {
01083 synchronized (out) {
01084 if (((ServeOutputStream) out).isReturnedAsWriter())
01085 throw new IllegalStateException("Already returned as a writer");
01086 ((ServeOutputStream) out).setReturnedAsStream(true);
01087 }
01088 return out;
01089 }
01090
01092
01093
01094
01095
01096
01097
01098 public PrintWriter getWriter() throws IOException {
01099 synchronized (out) {
01100 if (((ServeOutputStream) out).isReturnedAsStream())
01101 throw new IllegalStateException("Already was returned as servlet output stream");
01102 ((ServeOutputStream) out).setReturnedAsWriter(true);
01103 }
01104 String encoding = getCharacterEncoding();
01105 if (encoding != null) {
01106
01107 printWriter = new PrintWriter(new OutputStreamWriter(out, encoding));
01108 } else {
01109
01110 printWriter = new PrintWriter(out);
01111 }
01112 return printWriter;
01113 }
01114
01123
01124 public boolean isCommitted() {
01125 return headersWritten;
01126 }
01127
01134 public void reset() {
01135 if (!isCommitted()) {
01136 resHeaderNames.clear();
01137 } else
01138 throw new IllegalStateException("Header have already been committed.");
01139 }
01140
01141 public void resetBuffer() {
01142 throw new IllegalStateException("The method not implemented");
01143 }
01144
01146
01147
01148
01149 public void sendError(int resCode, String resMessage) throws IOException {
01150 setStatus(resCode, resMessage);
01151 realSendError();
01152 }
01153
01155
01156
01157
01158 public void sendError(int resCode) throws IOException {
01159 setStatus(resCode);
01160 realSendError();
01161 }
01162
01164
01165
01166
01167 public void sendRedirect(String location) throws IOException {
01168 if (isCommitted())
01169 throw new IllegalStateException(
01170 "Can not redirect, headers have been already written");
01171 synchronized (out) {
01172
01173 ((ServeOutputStream) out).setReturnedAsStream(true);
01174 ((ServeOutputStream) out).setReturnedAsWriter(true);
01175 }
01176 setHeader("Location", location);
01177 setStatus(SC_MOVED_TEMPORARILY);
01178 setContentType("text/html");
01179 StringBuffer sb = new StringBuffer(200);
01180 sb.append("<HTML><HEAD>" + "<TITLE>" + SC_MOVED_TEMPORARILY
01181 + " Moved</TITLE>" + "</HEAD><BODY BGCOLOR=\"#F1D0F2\">"
01182 + "<H2>" + SC_MOVED_TEMPORARILY + " Moved</H2>"
01183 + "This document has moved <a href=" + location + ">here.<HR>");
01184 Identification.writeAddress(sb);
01185 sb.append("</BODY></HTML>");
01186 setContentLength(sb.length());
01187
01188 out.print(sb.toString());
01189 out.flush();
01190 }
01191
01192
01193
01194 public void setBufferSize(int size) {
01195 }
01196
01198
01199 public void setContentLength(int length) {
01200 setIntHeader(CONTENTLENGTH, length);
01201 }
01202
01204
01205 public void setContentType(String type) {
01206 setHeader(CONTENTTYPE, type != null ? type : "Unknown");
01207 }
01208
01210
01211
01212 public void setDateHeader(String name, long value) {
01213 setHeader(name, expdatefmt.format(new Date(value)));
01214 }
01215
01217
01218
01219 public void setHeader(String name, String value) {
01220 resHeaderNames.put(name, value);
01221 }
01222
01224
01225
01226 public void setIntHeader(String name, int value) {
01227 setHeader(name, Integer.toString(value));
01228 }
01229
01238 public void setLocale(Locale locale) {
01239 this.locale = locale;
01240 }
01241
01243
01244 public void setStatus(int resCode) {
01245 switch (resCode) {
01246 case SC_CONTINUE:
01247 setStatus(resCode, "Continue");
01248 break;
01249 case SC_SWITCHING_PROTOCOLS:
01250 setStatus(resCode, "Switching protocols");
01251 break;
01252 case SC_OK:
01253 setStatus(resCode, "Ok");
01254 break;
01255 case SC_CREATED:
01256 setStatus(resCode, "Created");
01257 break;
01258 case SC_ACCEPTED:
01259 setStatus(resCode, "Accepted");
01260 break;
01261 case SC_NON_AUTHORITATIVE_INFORMATION:
01262 setStatus(resCode, "Non-authoritative");
01263 break;
01264 case SC_NO_CONTENT:
01265 setStatus(resCode, "No content");
01266 break;
01267 case SC_RESET_CONTENT:
01268 setStatus(resCode, "Reset content");
01269 break;
01270 case SC_PARTIAL_CONTENT:
01271 setStatus(resCode, "Partial content");
01272 break;
01273 case SC_MULTIPLE_CHOICES:
01274 setStatus(resCode, "Multiple choices");
01275 break;
01276 case SC_MOVED_PERMANENTLY:
01277 setStatus(resCode, "Moved permanentently");
01278 break;
01279 case SC_MOVED_TEMPORARILY:
01280 setStatus(resCode, "Moved temporarily");
01281 break;
01282 case SC_SEE_OTHER:
01283 setStatus(resCode, "See other");
01284 break;
01285 case SC_NOT_MODIFIED:
01286 setStatus(resCode, "Not modified");
01287 break;
01288 case SC_USE_PROXY:
01289 setStatus(resCode, "Use proxy");
01290 break;
01291 case SC_BAD_REQUEST:
01292 setStatus(resCode, "Bad request");
01293 break;
01294 case SC_UNAUTHORIZED:
01295 setStatus(resCode, "Unauthorized");
01296 break;
01297 case SC_PAYMENT_REQUIRED:
01298 setStatus(resCode, "Payment required");
01299 break;
01300 case SC_FORBIDDEN:
01301 setStatus(resCode, "Forbidden");
01302 break;
01303 case SC_NOT_FOUND:
01304 setStatus(resCode, "Not found");
01305 break;
01306 case SC_METHOD_NOT_ALLOWED:
01307 setStatus(resCode, "Method not allowed");
01308 break;
01309 case SC_NOT_ACCEPTABLE:
01310 setStatus(resCode, "Not acceptable");
01311 break;
01312 case SC_PROXY_AUTHENTICATION_REQUIRED:
01313 setStatus(resCode, "Proxy auth required");
01314 break;
01315 case SC_REQUEST_TIMEOUT:
01316 setStatus(resCode, "Request timeout");
01317 break;
01318 case SC_CONFLICT:
01319 setStatus(resCode, "Conflict");
01320 break;
01321 case SC_GONE:
01322 setStatus(resCode, "Gone");
01323 break;
01324 case SC_LENGTH_REQUIRED:
01325 setStatus(resCode, "Length required");
01326 break;
01327 case SC_PRECONDITION_FAILED:
01328 setStatus(resCode, "Precondition failed");
01329 break;
01330 case SC_REQUEST_ENTITY_TOO_LARGE:
01331 setStatus(resCode, "Request entity too large");
01332 break;
01333 case SC_REQUEST_URI_TOO_LONG:
01334 setStatus(resCode, "Request URI too large");
01335 break;
01336 case SC_UNSUPPORTED_MEDIA_TYPE:
01337 setStatus(resCode, "Unsupported media type");
01338 break;
01339 case SC_INTERNAL_SERVER_ERROR:
01340 setStatus(resCode, "Internal server error");
01341 break;
01342 case SC_NOT_IMPLEMENTED:
01343 setStatus(resCode, "Not implemented");
01344 break;
01345 case SC_BAD_GATEWAY:
01346 setStatus(resCode, "Bad gateway");
01347 break;
01348 case SC_SERVICE_UNAVAILABLE:
01349 setStatus(resCode, "Service unavailable");
01350 break;
01351 case SC_GATEWAY_TIMEOUT:
01352 setStatus(resCode, "Gateway timeout");
01353 break;
01354 case SC_HTTP_VERSION_NOT_SUPPORTED:
01355 setStatus(resCode, "HTTP version not supported");
01356 break;
01357 default:
01358 setStatus(resCode, "");
01359 break;
01360 }
01361 }
01362
01364
01365
01366 public void setStatus(int resCode, String resMessage) {
01367
01368
01369
01370 this.resCode = resCode;
01371 this.resMessage = resMessage;
01372 }
01373
01374
01375
01376
01377 }