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 void setRequestURI(String uri) {
00775 reqUriPath = uri;
00776 }
00777
00778 public StringBuffer getRequestURL() {
00779 return new StringBuffer().append(getScheme()).append("://").append(this.getServerName())
00780 .append(webserver.port == 80 ? "" : ":"+String.valueOf(webserver.port)).append(getRequestURI());
00781 }
00782
00784
00785
00786
00787
00788 public String getScheme() {
00789 if (socket.getClass().getName().toUpperCase().indexOf("SSL") < 0)
00790 return "http";
00791 else
00792 return "https";
00793 }
00794
00796
00797
00798 public String getServerName() {
00799 String serverName;
00800 serverName = getHeader("Host");
00801 if (serverName != null && serverName.length() > 0) {
00802 int colon = serverName.indexOf(':');
00803 if (colon >= 0) {
00804 if (colon < serverName.length()) serverName = serverName.substring(0, colon);
00805 }
00806 }
00807
00808 if (serverName == null) {
00809 try {
00810 serverName = InetAddress.getLocalHost().getHostName();
00811 } catch (java.net.UnknownHostException ignore) {
00812 serverName = "127.0.0.0";
00813 }
00814 }
00815
00816 int slash = serverName.indexOf("/");
00817 if (slash >= 0)
00818 serverName = serverName.substring(slash + 1);
00819 return serverName;
00820 }
00821
00823
00824
00825 public int getServerPort() {
00826 return socket.getLocalPort();
00827 }
00828
00829 public String getServletPath() {
00830
00831
00832
00833 return uriLen > 0 ? reqUriPath.substring(0, uriLen) : "";
00834 }
00835
00836 public HttpSession getSession() {
00837 return this.getSession(true);
00838 }
00839
00840 public HttpSession getSession(boolean create) {
00841
00842 SessionContext session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00843 if (session == null) {
00844 synchronized (SessionContextManager.getManager()) {
00845 session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00846 if (session == null) {
00847 session = SessionContextManager.getManager().createSessionContext("OPENMOBILEISSESSION");
00848 }
00849 }
00850 }
00851 SessionContextManager.getManager().joinSessionContext(session.getId());
00852 return SessionContextManager.getManager().getSessionContext();
00853 }
00854
00855 public Principal getUserPrincipal() {
00856
00857 return null;
00858 }
00859
00860 public boolean isRequestedSessionIdFromCookie() {
00861
00862 return false;
00863 }
00864
00865 public boolean isRequestedSessionIdFromURL() {
00866
00867 return false;
00868 }
00869
00870 public boolean isRequestedSessionIdFromUrl() {
00871
00872 return false;
00873 }
00874
00875 public boolean isRequestedSessionIdValid() {
00876 HttpSession session = this.getSession();
00877 if (session != null) {
00878 return true;
00879 }
00880 return false;
00881 }
00882
00883 public boolean isSecure() {
00884 return false;
00885 }
00886
00887 public boolean isUserInRole(String arg0) {
00888
00889 return false;
00890 }
00891
00892 public void removeAttribute(String name) {
00893 attributes.remove(name);
00894 }
00895
00896 public void setAttribute(String key, Object o) {
00897 attributes.put(key, o);
00898 }
00899
00907 public void setCharacterEncoding(String _enc) {
00908 reqCharEncoding = _enc;
00909 }
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00929
00930
00931
00932 public String getCharacterEncoding() {
00933 String ct = (String) resHeaderNames.get(CONTENTTYPE);
00934 if (ct != null) {
00935 int scp = ct.indexOf(';');
00936 if (scp > 0) {
00937 scp = ct.toLowerCase().indexOf("charset=", scp);
00938 if (scp >= 0) {
00939 ct = ct.substring(scp + 8);
00940 scp = ct.indexOf(' ');
00941 if (scp > 0)
00942 ct = ct.substring(0, scp);
00943 scp = ct.indexOf(';');
00944 if (scp > 0)
00945 ct = ct.substring(0, scp);
00946 return ct;
00947 }
00948 }
00949 }
00950 return null;
00951 }
00952
00953 public Locale getLocale() {
00954 return locale;
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
00987
00989
00990 public void addCookie(Cookie cookie) {
00991
00992 }
00993
00994 public void addDateHeader(String header, long date) {
00995 addHeader(header, expdatefmt.format(new Date(date)));
00996 }
00997
00998 public void addHeader(String header, String value) {
00999 Object o = resHeaderNames.get(header);
01000 if (o == null)
01001 setHeader(header, value);
01002 else {
01003 if (o instanceof String[]) {
01004 String[] oldVal = (String[]) o;
01005 String[] newVal = new String[oldVal.length + 1];
01006 System.arraycopy(oldVal, 0, newVal, 0, oldVal.length);
01007 newVal[oldVal.length] = value;
01008 resHeaderNames.put(header, newVal);
01009 } else if (o instanceof String) {
01010 String[] newVal = new String[2];
01011 newVal[0] = (String) o;
01012 newVal[1] = value;
01013 resHeaderNames.put(header, newVal);
01014 } else
01015 throw new RuntimeException("Invalid content of header hash - "
01016 + o.getClass().getName());
01017 }
01018 }
01019
01020 public void addIntHeader(String header, int value) {
01021 addHeader(header, Integer.toString(value));
01022 }
01023
01025
01026 public boolean containsHeader(String name) {
01027 return resHeaderNames.contains(name);
01028 }
01029
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 public String encodeRedirectUrl(String url) {
01042 return url;
01043 }
01044
01045 public String encodeRedirectURL(String url) {
01046 return url;
01047 }
01048
01049
01050
01051
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 public String encodeUrl(String url) {
01063 return url;
01064 }
01065
01066
01067 public String encodeURL(String url) {
01068 return url;
01069 }
01070
01071
01072
01073 public void flushBuffer() {
01074 }
01075
01076 public int getBufferSize() {
01077 return 0;
01078 }
01079
01081 public ServletOutputStream getOutputStream() throws IOException {
01082 synchronized (out) {
01083 if (((ServeOutputStream) out).isReturnedAsWriter())
01084 throw new IllegalStateException("Already returned as a writer");
01085 ((ServeOutputStream) out).setReturnedAsStream(true);
01086 }
01087 return out;
01088 }
01089
01091
01092
01093
01094
01095
01096
01097 public PrintWriter getWriter() throws IOException {
01098 synchronized (out) {
01099 if (((ServeOutputStream) out).isReturnedAsStream())
01100 throw new IllegalStateException("Already was returned as servlet output stream");
01101 ((ServeOutputStream) out).setReturnedAsWriter(true);
01102 }
01103 String encoding = getCharacterEncoding();
01104 if (encoding != null) {
01105
01106 printWriter = new PrintWriter(new OutputStreamWriter(out, encoding));
01107 } else {
01108
01109 printWriter = new PrintWriter(out);
01110 }
01111 return printWriter;
01112 }
01113
01122
01123 public boolean isCommitted() {
01124 return headersWritten;
01125 }
01126
01133 public void reset() {
01134 if (!isCommitted()) {
01135 resHeaderNames.clear();
01136 } else
01137 throw new IllegalStateException("Header have already been committed.");
01138 }
01139
01140 public void resetBuffer() {
01141 throw new IllegalStateException("The method not implemented");
01142 }
01143
01145
01146
01147
01148 public void sendError(int resCode, String resMessage) throws IOException {
01149 setStatus(resCode, resMessage);
01150 realSendError();
01151 }
01152
01154
01155
01156
01157 public void sendError(int resCode) throws IOException {
01158 setStatus(resCode);
01159 realSendError();
01160 }
01161
01163
01164
01165
01166 public void sendRedirect(String location) throws IOException {
01167 if (isCommitted())
01168 throw new IllegalStateException(
01169 "Can not redirect, headers have been already written");
01170 synchronized (out) {
01171
01172 ((ServeOutputStream) out).setReturnedAsStream(true);
01173 ((ServeOutputStream) out).setReturnedAsWriter(true);
01174 }
01175 setHeader("Location", location);
01176 setStatus(SC_MOVED_TEMPORARILY);
01177 setContentType("text/html");
01178 StringBuffer sb = new StringBuffer(200);
01179 sb.append("<HTML><HEAD>" + "<TITLE>" + SC_MOVED_TEMPORARILY
01180 + " Moved</TITLE>" + "</HEAD><BODY BGCOLOR=\"#F1D0F2\">"
01181 + "<H2>" + SC_MOVED_TEMPORARILY + " Moved</H2>"
01182 + "This document has moved <a href=" + location + ">here.<HR>");
01183 Identification.writeAddress(sb);
01184 sb.append("</BODY></HTML>");
01185 setContentLength(sb.length());
01186
01187 out.print(sb.toString());
01188 out.flush();
01189 }
01190
01191
01192
01193 public void setBufferSize(int size) {
01194 }
01195
01197
01198 public void setContentLength(int length) {
01199 setIntHeader(CONTENTLENGTH, length);
01200 }
01201
01203
01204 public void setContentType(String type) {
01205 setHeader(CONTENTTYPE, type != null ? type : "Unknown");
01206 }
01207
01209
01210
01211 public void setDateHeader(String name, long value) {
01212 setHeader(name, expdatefmt.format(new Date(value)));
01213 }
01214
01216
01217
01218 public void setHeader(String name, String value) {
01219 resHeaderNames.put(name, value);
01220 }
01221
01223
01224
01225 public void setIntHeader(String name, int value) {
01226 setHeader(name, Integer.toString(value));
01227 }
01228
01237 public void setLocale(Locale locale) {
01238 this.locale = locale;
01239 }
01240
01242
01243 public void setStatus(int resCode) {
01244 switch (resCode) {
01245 case SC_CONTINUE:
01246 setStatus(resCode, "Continue");
01247 break;
01248 case SC_SWITCHING_PROTOCOLS:
01249 setStatus(resCode, "Switching protocols");
01250 break;
01251 case SC_OK:
01252 setStatus(resCode, "Ok");
01253 break;
01254 case SC_CREATED:
01255 setStatus(resCode, "Created");
01256 break;
01257 case SC_ACCEPTED:
01258 setStatus(resCode, "Accepted");
01259 break;
01260 case SC_NON_AUTHORITATIVE_INFORMATION:
01261 setStatus(resCode, "Non-authoritative");
01262 break;
01263 case SC_NO_CONTENT:
01264 setStatus(resCode, "No content");
01265 break;
01266 case SC_RESET_CONTENT:
01267 setStatus(resCode, "Reset content");
01268 break;
01269 case SC_PARTIAL_CONTENT:
01270 setStatus(resCode, "Partial content");
01271 break;
01272 case SC_MULTIPLE_CHOICES:
01273 setStatus(resCode, "Multiple choices");
01274 break;
01275 case SC_MOVED_PERMANENTLY:
01276 setStatus(resCode, "Moved permanentently");
01277 break;
01278 case SC_MOVED_TEMPORARILY:
01279 setStatus(resCode, "Moved temporarily");
01280 break;
01281 case SC_SEE_OTHER:
01282 setStatus(resCode, "See other");
01283 break;
01284 case SC_NOT_MODIFIED:
01285 setStatus(resCode, "Not modified");
01286 break;
01287 case SC_USE_PROXY:
01288 setStatus(resCode, "Use proxy");
01289 break;
01290 case SC_BAD_REQUEST:
01291 setStatus(resCode, "Bad request");
01292 break;
01293 case SC_UNAUTHORIZED:
01294 setStatus(resCode, "Unauthorized");
01295 break;
01296 case SC_PAYMENT_REQUIRED:
01297 setStatus(resCode, "Payment required");
01298 break;
01299 case SC_FORBIDDEN:
01300 setStatus(resCode, "Forbidden");
01301 break;
01302 case SC_NOT_FOUND:
01303 setStatus(resCode, "Not found");
01304 break;
01305 case SC_METHOD_NOT_ALLOWED:
01306 setStatus(resCode, "Method not allowed");
01307 break;
01308 case SC_NOT_ACCEPTABLE:
01309 setStatus(resCode, "Not acceptable");
01310 break;
01311 case SC_PROXY_AUTHENTICATION_REQUIRED:
01312 setStatus(resCode, "Proxy auth required");
01313 break;
01314 case SC_REQUEST_TIMEOUT:
01315 setStatus(resCode, "Request timeout");
01316 break;
01317 case SC_CONFLICT:
01318 setStatus(resCode, "Conflict");
01319 break;
01320 case SC_GONE:
01321 setStatus(resCode, "Gone");
01322 break;
01323 case SC_LENGTH_REQUIRED:
01324 setStatus(resCode, "Length required");
01325 break;
01326 case SC_PRECONDITION_FAILED:
01327 setStatus(resCode, "Precondition failed");
01328 break;
01329 case SC_REQUEST_ENTITY_TOO_LARGE:
01330 setStatus(resCode, "Request entity too large");
01331 break;
01332 case SC_REQUEST_URI_TOO_LONG:
01333 setStatus(resCode, "Request URI too large");
01334 break;
01335 case SC_UNSUPPORTED_MEDIA_TYPE:
01336 setStatus(resCode, "Unsupported media type");
01337 break;
01338 case SC_INTERNAL_SERVER_ERROR:
01339 setStatus(resCode, "Internal server error");
01340 break;
01341 case SC_NOT_IMPLEMENTED:
01342 setStatus(resCode, "Not implemented");
01343 break;
01344 case SC_BAD_GATEWAY:
01345 setStatus(resCode, "Bad gateway");
01346 break;
01347 case SC_SERVICE_UNAVAILABLE:
01348 setStatus(resCode, "Service unavailable");
01349 break;
01350 case SC_GATEWAY_TIMEOUT:
01351 setStatus(resCode, "Gateway timeout");
01352 break;
01353 case SC_HTTP_VERSION_NOT_SUPPORTED:
01354 setStatus(resCode, "HTTP version not supported");
01355 break;
01356 default:
01357 setStatus(resCode, "");
01358 break;
01359 }
01360 }
01361
01363
01364
01365 public void setStatus(int resCode, String resMessage) {
01366
01367
01368
01369 this.resCode = resCode;
01370 this.resMessage = resMessage;
01371 }
01372
01373
01374
01375
01376 }