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 if (servlete instanceof SingleThreadModel)
00364 synchronized (servlete) {
00365 servlete.service((ServletRequest) this,
00366 (ServletResponse) this);
00367 }
00368 else {
00369 servlete.service((ServletRequest) this, (ServletResponse) this);
00370 }
00371 if (((ServeOutputStream)out).isReturnedAsWriter() && printWriter != null) {
00372 printWriter.flush();
00373 } else {
00374 out.flush();
00375 }
00376 } catch (IOException e) {
00377 e.printStackTrace();
00378 problem("IO problem running servlet: " + e.toString(),
00379 SC_BAD_REQUEST);
00380 } catch (ServletException e) {
00381 e.printStackTrace();
00382 problem("problem running servlet: " + e.toString(), SC_BAD_REQUEST);
00383 } catch (Exception e) {
00384 e.printStackTrace();
00385 problem("unexpected problem running servlet: " + e.toString(),
00386 SC_INTERNAL_SERVER_ERROR);
00387 }
00388 }
00389
00390 private boolean authenticate() throws IOException {
00391
00392 return true;
00393 }
00394
00395
00396 private void problem(String logMessage, int resCode) {
00397 LogManager.traceError(LogServices.WEBSERVICE, logMessage);
00398 try {
00399 sendError(resCode);
00400 } catch (IllegalStateException e) {
00401 } catch (IOException e) {
00402 }
00403 }
00404
00405 private Hashtable getParametersFromRequest() {
00406 Hashtable result = null;
00407
00408
00409 if ("GET".equals(reqMethod)) {
00410 if (reqQuery != null)
00411 try {
00412 result = HttpUtils.parseQueryString(reqQuery);
00413 } catch (IllegalArgumentException ex) {
00414 }
00415 } else if ("POST".equals(reqMethod))
00416 if (WWWFORMURLENCODE.equals(getContentType()))
00417 try {
00418 result = HttpUtils.parsePostData(getContentLength(), getInputStream());
00419 if (reqQuery != null && reqQuery.length() > 0) {
00420 Acme.Utils.putAll(result, HttpUtils.parseQueryString(reqQuery));
00421 }
00422 } catch (Exception ex) {
00423 LogManager.traceError(0, ex);
00424 LogManager.traceError(LogServices.WEBSERVICE, "Exception " + ex + " at parsing post data of length " + getContentLength());
00425 }
00426 else
00427 try {
00428 if (reqQuery != null)
00429 result = HttpUtils.parseQueryString(reqQuery);
00430 } catch (Exception ex) {
00431 }
00432 return result != null ? result : EMPTYHASHTABLE;
00433 }
00434
00435 private void realSendError() throws IOException {
00436 if (isCommitted())
00437 throw new IllegalStateException(
00438 "Can not send error, headers have been already written");
00439 synchronized (out) {
00440
00441 ((ServeOutputStream) out).setReturnedAsStream(true);
00442 ((ServeOutputStream) out).setReturnedAsWriter(true);
00443 }
00444 setContentType("text/html");
00445 StringBuffer sb = new StringBuffer(100);
00446 sb.append("<HTML><HEAD>").append(
00447 "<TITLE>" + resCode + " " + resMessage + "</TITLE>").append(
00448 "</HEAD><BODY BGCOLOR=\"#F1D0F2\">").append(
00449 "<H2>" + resCode + " " + resMessage + "</H2>").append("<HR>");
00450 Identification.writeAddress(sb);
00451 sb.append("</BODY></HTML>");
00452 setContentLength(sb.length());
00453 out.print(sb.toString());
00454 out.flush();
00455 }
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
00482
00483
00484 public Object getAttribute(String name) {
00485 return attributes.get(name);
00486 }
00487
00488
00489 public Enumeration getAttributeNames() {
00490 return attributes.keys();
00491 }
00492
00493 public String getAuthType() {
00494
00495 return null;
00496 }
00497
00499
00500 public int getContentLength() {
00501 try {
00502 return this.getIntHeader(CONTENTLENGTH);
00503 } catch (Exception ex) {
00504 return -1;
00505 }
00506 }
00507
00509
00510
00511 public String getContentType() {
00512 return getHeader(CONTENTTYPE);
00513 }
00514
00515 public String getContextPath() {
00516 return "";
00517 }
00518
00519 public Cookie[] getCookies() {
00520
00521 return null;
00522 }
00523
00524 public long getDateHeader(String name) {
00525 String val = getHeader(name);
00526 if (val == null)
00527 return 0;
00528 try {
00529 return headerdateformat.parse(val).getTime();
00530 } catch (Exception e) {
00531 throw new IllegalArgumentException("Value " + val
00532 + " can't be converted to Date using "
00533 + headerdateformat.toPattern());
00534 }
00535 }
00536
00537 public String getHeader(String name) {
00538 int i = reqHeaderNames.indexOf(name.toLowerCase());
00539 if (i == -1)
00540 return null;
00541 return (String) reqHeaderValues.elementAt(i);
00542 }
00543
00544 public Enumeration getHeaderNames() {
00545 return reqHeaderNames.elements();
00546 }
00547
00548 public Enumeration getHeaders(String header) {
00549 Vector result = new Vector();
00550 int i = -1;
00551 while ((i = reqHeaderNames.indexOf(header.toLowerCase(), i + 1)) >= 0)
00552 result.addElement(reqHeaderValues.elementAt(i));
00553 return result.elements();
00554 }
00555
00557
00558
00559 public ServletInputStream getInputStream() throws IOException {
00560 synchronized (in) {
00561 if (((ServeInputStream) in).isReturnedAsReader())
00562 throw new IllegalStateException("Already returned as a reader.");
00563 ((ServeInputStream) in).setReturnedAsReader(true);
00564 }
00565 return in;
00566 }
00567
00569
00570 public int getIntHeader(String name) {
00571 String val = getHeader(name);
00572 if (val == null)
00573 return -1;
00574
00575
00576
00577
00578 return Integer.parseInt(val);
00579 }
00580
00591 public String getLocalAddr() {
00592 return null;
00593 }
00594
00595
00596 public Enumeration getLocales() {
00597
00598
00599 return null;
00600 }
00601
00611 public String getLocalName() {
00612 return null;
00613 }
00614
00623 public int getLocalPort() {
00624 return webserver.port;
00625 }
00626
00627 public String getMethod() {
00628 return reqMethod;
00629 }
00630
00632
00633
00634 public String getParameter(String name) {
00635 String[] params = getParameterValues(name);
00636 if (params == null || params.length == 0)
00637 return null;
00638
00639 return params[0];
00640 }
00641
00651 public java.util.Map getParameterMap() {
00652 return (java.util.Map) formParameters;
00653 }
00654
00656 public Enumeration getParameterNames() {
00657 if (formParameters == null)
00658 formParameters = getParametersFromRequest();
00659 return formParameters.keys();
00660 }
00661
00663
00664 public String[] getParameterValues(String name) {
00665 if (formParameters == null)
00666 getParameterNames();
00667
00668 return (String[]) formParameters.get(name);
00669 }
00670
00671 public String getPathInfo() {
00672
00673
00674
00675 return uriLen >= reqUriPath.length() ? null : reqUriPath.substring(uriLen);
00676 }
00677
00678 public String getPathTranslated() {
00679
00680
00681
00682 return getRealPath(getPathInfo());
00683 }
00684
00686
00687
00688 public String getProtocol() {
00689 return reqProtocol;
00690 }
00691
00692
00693
00694 public String getQueryString() {
00695 return reqQuery;
00696 }
00697
00699
00700
00701
00702 public BufferedReader getReader() throws IOException {
00703 synchronized (in) {
00704 if (((ServeInputStream) in).isReturnedAsStream())
00705 throw new IllegalStateException("Already returned as a stream.");
00706 ((ServeInputStream) in).setReturnedAsStream(true);
00707 }
00708 if (reqCharEncoding != null)
00709 try {
00710 return new BufferedReader(new InputStreamReader(in, reqCharEncoding));
00711 } catch (UnsupportedEncodingException uee) {
00712 }
00713 return new BufferedReader(new InputStreamReader(in));
00714 }
00715
00717
00718
00719
00720
00721
00722 public String getRealPath(String path) {
00723 return webserver.getRealPath(path);
00724 }
00725
00727
00728 public String getRemoteAddr() {
00729 return socket.getInetAddress().getHostAddress().toString();
00730 }
00731
00733
00734
00735 public String getRemoteHost() {
00736 String result = socket.getInetAddress().getHostName();
00737 return result != null ? result : getRemoteAddr();
00738 }
00739
00748 public int getRemotePort() {
00749
00750 return webserver.port;
00751 }
00752
00754
00755 public String getRemoteUser() {
00756
00757 return null;
00758 }
00759
00760 public RequestDispatcher getRequestDispatcher(String urlpath) {
00761
00762 return null;
00763 }
00764
00765 public String getRequestedSessionId() {
00766
00767 return this.getSession().getId();
00768 }
00769
00770 public String getRequestURI() {
00771 return reqUriPath;
00772 }
00773
00774 public StringBuffer getRequestURL() {
00775 return new StringBuffer().append(getScheme()).append("://").append(this.getServerName())
00776 .append(webserver.port == 80 ? "" : ":"+String.valueOf(webserver.port)).append(getRequestURI());
00777 }
00778
00780
00781
00782
00783
00784 public String getScheme() {
00785 if (socket.getClass().getName().toUpperCase().indexOf("SSL") < 0)
00786 return "http";
00787 else
00788 return "https";
00789 }
00790
00792
00793
00794 public String getServerName() {
00795 String serverName;
00796 int serverPort = 80;
00797 serverName = getHeader("Host");
00798 if (serverName != null && serverName.length() > 0) {
00799 int colon = serverName.indexOf(':');
00800 if (colon >= 0) {
00801 if (colon < serverName.length())
00802 serverPort = Integer.parseInt(serverName.substring(colon + 1));
00803 serverName = serverName.substring(0, colon);
00804 }
00805 }
00806
00807 if (serverName == null) {
00808 try {
00809 serverName = InetAddress.getLocalHost().getHostName();
00810 } catch (java.net.UnknownHostException ignore) {
00811 serverName = "127.0.0.0";
00812 }
00813 }
00814
00815 int slash = serverName.indexOf("/");
00816 if (slash >= 0)
00817 serverName = serverName.substring(slash + 1);
00818 return serverName;
00819 }
00820
00822
00823
00824 public int getServerPort() {
00825 return socket.getLocalPort();
00826 }
00827
00828 public String getServletPath() {
00829
00830
00831
00832 return uriLen > 0 ? reqUriPath.substring(0, uriLen) : "";
00833 }
00834
00835 public HttpSession getSession() {
00836 return this.getSession(true);
00837 }
00838
00839 public HttpSession getSession(boolean create) {
00840
00841 SessionContext session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00842 if (session == null) {
00843 synchronized (SessionContextManager.getManager()) {
00844 session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00845 if (session == null) {
00846 session = SessionContextManager.getManager().createSessionContext("OPENMOBILEISSESSION");
00847 }
00848 }
00849 }
00850 SessionContextManager.getManager().joinSessionContext(session.getId());
00851 return SessionContextManager.getManager().getSessionContext();
00852 }
00853
00854 public Principal getUserPrincipal() {
00855
00856 return null;
00857 }
00858
00859 public boolean isRequestedSessionIdFromCookie() {
00860
00861 return false;
00862 }
00863
00864 public boolean isRequestedSessionIdFromURL() {
00865
00866 return false;
00867 }
00868
00869 public boolean isRequestedSessionIdFromUrl() {
00870
00871 return false;
00872 }
00873
00874 public boolean isRequestedSessionIdValid() {
00875 HttpSession session = this.getSession();
00876 if (session != null) {
00877 return true;
00878 }
00879 return false;
00880 }
00881
00882 public boolean isSecure() {
00883 return false;
00884 }
00885
00886 public boolean isUserInRole(String arg0) {
00887
00888 return false;
00889 }
00890
00891 public void removeAttribute(String name) {
00892
00893 }
00894
00895 public void setAttribute(String key, Object o) {
00896 attributes.put(key, o);
00897 }
00898
00906 public void setCharacterEncoding(String _enc) {
00907 reqCharEncoding = _enc;
00908 }
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00928
00929
00930
00931 public String getCharacterEncoding() {
00932 String ct = (String) resHeaderNames.get(CONTENTTYPE);
00933 if (ct != null) {
00934 int scp = ct.indexOf(';');
00935 if (scp > 0) {
00936 scp = ct.toLowerCase().indexOf("charset=", scp);
00937 if (scp >= 0) {
00938 ct = ct.substring(scp + 8);
00939 scp = ct.indexOf(' ');
00940 if (scp > 0)
00941 ct = ct.substring(0, scp);
00942 scp = ct.indexOf(';');
00943 if (scp > 0)
00944 ct = ct.substring(0, scp);
00945 return ct;
00946 }
00947 }
00948 }
00949 return null;
00950 }
00951
00952 public Locale getLocale() {
00953 return locale;
00954 }
00955
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
00988
00989 public void addCookie(Cookie cookie) {
00990
00991 }
00992
00993 public void addDateHeader(String header, long date) {
00994 addHeader(header, expdatefmt.format(new Date(date)));
00995 }
00996
00997 public void addHeader(String header, String value) {
00998 Object o = resHeaderNames.get(header);
00999 if (o == null)
01000 setHeader(header, value);
01001 else {
01002 if (o instanceof String[]) {
01003 String[] oldVal = (String[]) o;
01004 String[] newVal = new String[oldVal.length + 1];
01005 System.arraycopy(oldVal, 0, newVal, 0, oldVal.length);
01006 newVal[oldVal.length] = value;
01007 resHeaderNames.put(header, newVal);
01008 } else if (o instanceof String) {
01009 String[] newVal = new String[2];
01010 newVal[0] = (String) o;
01011 newVal[1] = value;
01012 resHeaderNames.put(header, newVal);
01013 } else
01014 throw new RuntimeException("Invalid content of header hash - "
01015 + o.getClass().getName());
01016 }
01017 }
01018
01019 public void addIntHeader(String header, int value) {
01020 addHeader(header, Integer.toString(value));
01021 }
01022
01024
01025 public boolean containsHeader(String name) {
01026 return resHeaderNames.contains(name);
01027 }
01028
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 public String encodeRedirectUrl(String url) {
01041 return url;
01042 }
01043
01044 public String encodeRedirectURL(String url) {
01045 return url;
01046 }
01047
01048
01049
01050
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 public String encodeUrl(String url) {
01062 return url;
01063 }
01064
01065
01066 public String encodeURL(String url) {
01067 return url;
01068 }
01069
01070
01071
01072 public void flushBuffer() {
01073 }
01074
01075 public int getBufferSize() {
01076 return 0;
01077 }
01078
01080 public ServletOutputStream getOutputStream() throws IOException {
01081 synchronized (out) {
01082 if (((ServeOutputStream) out).isReturnedAsWriter())
01083 throw new IllegalStateException("Already returned as a writer");
01084 ((ServeOutputStream) out).setReturnedAsStream(true);
01085 }
01086 return out;
01087 }
01088
01090
01091
01092
01093
01094
01095
01096 public PrintWriter getWriter() throws IOException {
01097 synchronized (out) {
01098 if (((ServeOutputStream) out).isReturnedAsStream())
01099 throw new IllegalStateException("Already was returned as servlet output stream");
01100 ((ServeOutputStream) out).setReturnedAsWriter(true);
01101 }
01102 String encoding = getCharacterEncoding();
01103 if (encoding != null) {
01104
01105 printWriter = new PrintWriter(new OutputStreamWriter(out, encoding));
01106 } else {
01107
01108 printWriter = new PrintWriter(out);
01109 }
01110 return printWriter;
01111 }
01112
01121
01122 public boolean isCommitted() {
01123 return headersWritten;
01124 }
01125
01132 public void reset() {
01133 if (!isCommitted()) {
01134 resHeaderNames.clear();
01135 } else
01136 throw new IllegalStateException("Header have already been committed.");
01137 }
01138
01139 public void resetBuffer() {
01140 throw new IllegalStateException("The method not implemented");
01141 }
01142
01144
01145
01146
01147 public void sendError(int resCode, String resMessage) throws IOException {
01148 setStatus(resCode, resMessage);
01149 realSendError();
01150 }
01151
01153
01154
01155
01156 public void sendError(int resCode) throws IOException {
01157 setStatus(resCode);
01158 realSendError();
01159 }
01160
01162
01163
01164
01165 public void sendRedirect(String location) throws IOException {
01166 if (isCommitted())
01167 throw new IllegalStateException(
01168 "Can not redirect, headers have been already written");
01169 synchronized (out) {
01170
01171 ((ServeOutputStream) out).setReturnedAsStream(true);
01172 ((ServeOutputStream) out).setReturnedAsWriter(true);
01173 }
01174 setHeader("Location", location);
01175 setStatus(SC_MOVED_TEMPORARILY);
01176 setContentType("text/html");
01177 StringBuffer sb = new StringBuffer(200);
01178 sb.append("<HTML><HEAD>" + "<TITLE>" + SC_MOVED_TEMPORARILY
01179 + " Moved</TITLE>" + "</HEAD><BODY BGCOLOR=\"#F1D0F2\">"
01180 + "<H2>" + SC_MOVED_TEMPORARILY + " Moved</H2>"
01181 + "This document has moved <a href=" + location + ">here.<HR>");
01182 Identification.writeAddress(sb);
01183 sb.append("</BODY></HTML>");
01184 setContentLength(sb.length());
01185
01186 out.print(sb.toString());
01187 out.flush();
01188 }
01189
01190
01191
01192 public void setBufferSize(int size) {
01193 }
01194
01196
01197 public void setContentLength(int length) {
01198 setIntHeader(CONTENTLENGTH, length);
01199 }
01200
01202
01203 public void setContentType(String type) {
01204 setHeader(CONTENTTYPE, type != null ? type : "Unknown");
01205 }
01206
01208
01209
01210 public void setDateHeader(String name, long value) {
01211 setHeader(name, expdatefmt.format(new Date(value)));
01212 }
01213
01215
01216
01217 public void setHeader(String name, String value) {
01218 resHeaderNames.put(name, value);
01219 }
01220
01222
01223
01224 public void setIntHeader(String name, int value) {
01225 setHeader(name, Integer.toString(value));
01226 }
01227
01236 public void setLocale(Locale locale) {
01237 this.locale = locale;
01238 }
01239
01241
01242 public void setStatus(int resCode) {
01243 switch (resCode) {
01244 case SC_CONTINUE:
01245 setStatus(resCode, "Continue");
01246 break;
01247 case SC_SWITCHING_PROTOCOLS:
01248 setStatus(resCode, "Switching protocols");
01249 break;
01250 case SC_OK:
01251 setStatus(resCode, "Ok");
01252 break;
01253 case SC_CREATED:
01254 setStatus(resCode, "Created");
01255 break;
01256 case SC_ACCEPTED:
01257 setStatus(resCode, "Accepted");
01258 break;
01259 case SC_NON_AUTHORITATIVE_INFORMATION:
01260 setStatus(resCode, "Non-authoritative");
01261 break;
01262 case SC_NO_CONTENT:
01263 setStatus(resCode, "No content");
01264 break;
01265 case SC_RESET_CONTENT:
01266 setStatus(resCode, "Reset content");
01267 break;
01268 case SC_PARTIAL_CONTENT:
01269 setStatus(resCode, "Partial content");
01270 break;
01271 case SC_MULTIPLE_CHOICES:
01272 setStatus(resCode, "Multiple choices");
01273 break;
01274 case SC_MOVED_PERMANENTLY:
01275 setStatus(resCode, "Moved permanentently");
01276 break;
01277 case SC_MOVED_TEMPORARILY:
01278 setStatus(resCode, "Moved temporarily");
01279 break;
01280 case SC_SEE_OTHER:
01281 setStatus(resCode, "See other");
01282 break;
01283 case SC_NOT_MODIFIED:
01284 setStatus(resCode, "Not modified");
01285 break;
01286 case SC_USE_PROXY:
01287 setStatus(resCode, "Use proxy");
01288 break;
01289 case SC_BAD_REQUEST:
01290 setStatus(resCode, "Bad request");
01291 break;
01292 case SC_UNAUTHORIZED:
01293 setStatus(resCode, "Unauthorized");
01294 break;
01295 case SC_PAYMENT_REQUIRED:
01296 setStatus(resCode, "Payment required");
01297 break;
01298 case SC_FORBIDDEN:
01299 setStatus(resCode, "Forbidden");
01300 break;
01301 case SC_NOT_FOUND:
01302 setStatus(resCode, "Not found");
01303 break;
01304 case SC_METHOD_NOT_ALLOWED:
01305 setStatus(resCode, "Method not allowed");
01306 break;
01307 case SC_NOT_ACCEPTABLE:
01308 setStatus(resCode, "Not acceptable");
01309 break;
01310 case SC_PROXY_AUTHENTICATION_REQUIRED:
01311 setStatus(resCode, "Proxy auth required");
01312 break;
01313 case SC_REQUEST_TIMEOUT:
01314 setStatus(resCode, "Request timeout");
01315 break;
01316 case SC_CONFLICT:
01317 setStatus(resCode, "Conflict");
01318 break;
01319 case SC_GONE:
01320 setStatus(resCode, "Gone");
01321 break;
01322 case SC_LENGTH_REQUIRED:
01323 setStatus(resCode, "Length required");
01324 break;
01325 case SC_PRECONDITION_FAILED:
01326 setStatus(resCode, "Precondition failed");
01327 break;
01328 case SC_REQUEST_ENTITY_TOO_LARGE:
01329 setStatus(resCode, "Request entity too large");
01330 break;
01331 case SC_REQUEST_URI_TOO_LONG:
01332 setStatus(resCode, "Request URI too large");
01333 break;
01334 case SC_UNSUPPORTED_MEDIA_TYPE:
01335 setStatus(resCode, "Unsupported media type");
01336 break;
01337 case SC_INTERNAL_SERVER_ERROR:
01338 setStatus(resCode, "Internal server error");
01339 break;
01340 case SC_NOT_IMPLEMENTED:
01341 setStatus(resCode, "Not implemented");
01342 break;
01343 case SC_BAD_GATEWAY:
01344 setStatus(resCode, "Bad gateway");
01345 break;
01346 case SC_SERVICE_UNAVAILABLE:
01347 setStatus(resCode, "Service unavailable");
01348 break;
01349 case SC_GATEWAY_TIMEOUT:
01350 setStatus(resCode, "Gateway timeout");
01351 break;
01352 case SC_HTTP_VERSION_NOT_SUPPORTED:
01353 setStatus(resCode, "HTTP version not supported");
01354 break;
01355 default:
01356 setStatus(resCode, "");
01357 break;
01358 }
01359 }
01360
01362
01363
01364 public void setStatus(int resCode, String resMessage) {
01365
01366
01367
01368 this.resCode = resCode;
01369 this.resMessage = resMessage;
01370 }
01371
01372
01373
01374
01375 }