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 }
00164
00165
00166 parseRequest();
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 try {
00177 this.execURI(this.reqUriPath);
00178 } catch (Exception e) {
00179 problem("Getting streams: " + e.getMessage(), SC_BAD_REQUEST);
00180 LogManager.traceError(0, e);
00181 } finally {
00182 try {
00183
00184 socket.close();
00185 } catch (IOException e) {
00186 org.openmobileis.common.util.log.LogManager
00187 .traceError(
00188 org.openmobileis.common.util.log.LogServices.WEBSERVICE,
00189 "Impossible to close socket : WebServerConnection");
00190 org.openmobileis.common.util.log.LogManager
00191 .traceError(
00192 org.openmobileis.common.util.log.LogServices.WEBSERVICE,
00193 e);
00194 }
00195 }
00196 }
00197
00198 private void parseRequest() {
00199 byte[] lineBytes = new byte[4096];
00200 int len;
00201 String line;
00202
00203 try {
00204
00205 len = in.readLine(lineBytes, 0, lineBytes.length);
00206 if (len == -1 || len == 0) {
00207 problem("Empty request", SC_BAD_REQUEST);
00208 return;
00209 }
00210 line = new String(lineBytes, 0, len);
00211 StringTokenizer ust = new StringTokenizer(line);
00212 reqProtocol = null;
00213 if (ust.hasMoreTokens()) {
00214 reqMethod = ust.nextToken();
00215 if (ust.hasMoreTokens()) {
00216 reqUriPath = Acme.Utils.urlDecoder(ust.nextToken());
00217 if (ust.hasMoreTokens()) {
00218 reqProtocol = ust.nextToken();
00219 oneOne = !reqProtocol.toUpperCase().equals("HTTP/1.0");
00220 reqMime = true;
00221
00222 String s;
00223 while ((s = ((ServeInputStream) in).readLine()) != null) {
00224 if (s.length() == 0)
00225 break;
00226
00227 int c = s.indexOf(':', 0);
00228 if (c > 0) {
00229 String key = s.substring(0, c).trim();
00230 String value = s.substring(c + 1, s.length())
00231 .trim();
00232 reqHeaderNames.addElement(key.toLowerCase());
00233 reqHeaderValues.addElement(value);
00234 } else {
00235 LogManager.traceError(LogServices.WEBSERVICE, "header field without ':'");
00236 }
00237 }
00238 } else {
00239 reqProtocol = "HTTP/0.9";
00240 oneOne = false;
00241 reqMime = false;
00242 }
00243 }
00244 }
00245 if (reqProtocol == null) {
00246 problem("Malformed request line", SC_BAD_REQUEST);
00247 return;
00248 }
00249
00250 if (oneOne) {
00251 String host = getHeader("host");
00252 if (host == null) {
00253 problem("Host header missing on HTTP/1.1 request",
00254 SC_BAD_REQUEST);
00255 return;
00256 }
00257 }
00258
00259
00260
00261
00262 int qmark = reqUriPath.indexOf('?');
00263 if (qmark > -1) {
00264 reqQuery = reqUriPath.substring(qmark + 1);
00265 reqUriPath = reqUriPath.substring(0, qmark);
00266 }
00267 if (CHUNKED.equals(getHeader(TRANSFERENCODING))) {
00268 setHeader(CONTENTLENGTH, null);
00269 ((ServeInputStream) in).chunking(true);
00270 }
00271
00272 } catch (IOException e) {
00273 problem("Reading request: " + e.getMessage(), SC_BAD_REQUEST);
00274 }
00275 }
00276
00277 private void execURI(String URI) throws ServletException {
00278
00279 if (URI.equals("/index")) {
00280 URI = "/services/index";
00281 reqUriPath = URI;
00282 }
00283 Object[] os = webserver.getServletByURLorClassName(URI);
00284 if (os[0] == null) {
00285 os = webserver.getServletByURLorClassName("defaultServlet");
00286 if (os[0] == null) {
00287 throw new ServletException(
00288 "WebServerConnection::execUri Unable to find file servlet");
00289 }
00290
00291 uriLen = 0;
00292 runServlet((HttpServlet) os[0]);
00293 } else {
00294 uriLen = ((Integer) os[1]).intValue();
00295 runServlet((HttpServlet) os[0]);
00296 }
00297 }
00298
00300
00301
00302 void writeHeaders() throws IOException {
00303 synchronized (this) {
00304 if (headersWritten)
00305 return;
00306
00307 headersWritten = true;
00308 }
00309 if (reqMime) {
00310
00311 out.println(reqProtocol + " " + resCode + " " + resMessage);
00312
00313 Enumeration he = resHeaderNames.keys();
00314 while (he.hasMoreElements()) {
00315 String name = (String) he.nextElement();
00316 Object o = resHeaderNames.get(name);
00317 if (o instanceof String) {
00318 String value = (String) o;
00319 if (value != null)
00320 out.println(name + ": " + value);
00321
00322
00323
00324
00325 } else if (o instanceof String[]) {
00326 String[] values = (String[]) o;
00327 out.println(name + ": " + values[0]);
00328 for (int i = 0; i < values.length; i++)
00329 out.print("," + values[i]);
00330 out.println();
00331 }
00332 }
00333
00334 out.println("Pragma: no-cache");
00335 out.println("Cache-Control: no-cache, must-revalidate");
00336 out.println("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
00337 out.println("Date: Mon, 26 Jul 1997 05:00:00 GMT");
00338
00339 out.println("Last-Modified: Mon, 26 Jul 1997 05:00:00 GMT");
00340 out.println("Connection: close" );
00341
00342 out.println();
00343 out.flush();
00344
00345 }
00346 }
00347
00348 private void runServlet(HttpServlet servlete) {
00349
00350 setStatus(SC_OK);
00351
00352
00353
00354
00355
00356
00357 try {
00358 authenticate();
00359 if (servlete instanceof SingleThreadModel)
00360 synchronized (servlete) {
00361 servlete.service((ServletRequest) this,
00362 (ServletResponse) this);
00363 }
00364 else {
00365 servlete.service((ServletRequest) this, (ServletResponse) this);
00366 }
00367 if (((ServeOutputStream)out).isReturnedAsWriter() && printWriter != null) {
00368 printWriter.flush();
00369 } else {
00370 out.flush();
00371 }
00372 } catch (IOException e) {
00373 e.printStackTrace();
00374 problem("IO problem running servlet: " + e.toString(),
00375 SC_BAD_REQUEST);
00376 } catch (ServletException e) {
00377 e.printStackTrace();
00378 problem("problem running servlet: " + e.toString(), SC_BAD_REQUEST);
00379 } catch (Exception e) {
00380 e.printStackTrace();
00381 problem("unexpected problem running servlet: " + e.toString(),
00382 SC_INTERNAL_SERVER_ERROR);
00383 }
00384 }
00385
00386 private boolean authenticate() throws IOException {
00387
00388 return true;
00389 }
00390
00391
00392 private void problem(String logMessage, int resCode) {
00393 LogManager.traceError(LogServices.WEBSERVICE, logMessage);
00394 try {
00395 sendError(resCode);
00396 } catch (IllegalStateException e) {
00397 } catch (IOException e) {
00398 }
00399 }
00400
00401 private Hashtable getParametersFromRequest() {
00402 Hashtable result = null;
00403
00404
00405 if ("GET".equals(reqMethod)) {
00406 if (reqQuery != null)
00407 try {
00408 result = HttpUtils.parseQueryString(reqQuery);
00409 } catch (IllegalArgumentException ex) {
00410 }
00411 } else if ("POST".equals(reqMethod))
00412 if (WWWFORMURLENCODE.equals(getContentType()))
00413 try {
00414 result = HttpUtils.parsePostData(getContentLength(), getInputStream());
00415 if (reqQuery != null && reqQuery.length() > 0) {
00416 Acme.Utils.putAll(result, HttpUtils.parseQueryString(reqQuery));
00417 }
00418 } catch (Exception ex) {
00419 LogManager.traceError(0, ex);
00420 LogManager.traceError(LogServices.WEBSERVICE, "Exception " + ex + " at parsing post data of length " + getContentLength());
00421 }
00422 else
00423 try {
00424 if (reqQuery != null)
00425 result = HttpUtils.parseQueryString(reqQuery);
00426 } catch (Exception ex) {
00427 }
00428 return result != null ? result : EMPTYHASHTABLE;
00429 }
00430
00431 private void realSendError() throws IOException {
00432 if (isCommitted())
00433 throw new IllegalStateException(
00434 "Can not send error, headers have been already written");
00435 synchronized (out) {
00436
00437 ((ServeOutputStream) out).setReturnedAsStream(true);
00438 ((ServeOutputStream) out).setReturnedAsWriter(true);
00439 }
00440 setContentType("text/html");
00441 StringBuffer sb = new StringBuffer(100);
00442 sb.append("<HTML><HEAD>").append(
00443 "<TITLE>" + resCode + " " + resMessage + "</TITLE>").append(
00444 "</HEAD><BODY BGCOLOR=\"#F1D0F2\">").append(
00445 "<H2>" + resCode + " " + resMessage + "</H2>").append("<HR>");
00446 Identification.writeAddress(sb);
00447 sb.append("</BODY></HTML>");
00448 setContentLength(sb.length());
00449 out.print(sb.toString());
00450 out.flush();
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00478
00479
00480 public Object getAttribute(String name) {
00481 return attributes.get(name);
00482 }
00483
00484
00485 public Enumeration getAttributeNames() {
00486 return attributes.keys();
00487 }
00488
00489 public String getAuthType() {
00490
00491 return null;
00492 }
00493
00495
00496 public int getContentLength() {
00497 try {
00498 return this.getIntHeader(CONTENTLENGTH);
00499 } catch (Exception ex) {
00500 return -1;
00501 }
00502 }
00503
00505
00506
00507 public String getContentType() {
00508 return getHeader(CONTENTTYPE);
00509 }
00510
00511 public String getContextPath() {
00512 return "";
00513 }
00514
00515 public Cookie[] getCookies() {
00516
00517 return null;
00518 }
00519
00520 public long getDateHeader(String name) {
00521 String val = getHeader(name);
00522 if (val == null)
00523 return 0;
00524 try {
00525 return headerdateformat.parse(val).getTime();
00526 } catch (Exception e) {
00527 throw new IllegalArgumentException("Value " + val
00528 + " can't be converted to Date using "
00529 + headerdateformat.toPattern());
00530 }
00531 }
00532
00533 public String getHeader(String name) {
00534 int i = reqHeaderNames.indexOf(name.toLowerCase());
00535 if (i == -1)
00536 return null;
00537 return (String) reqHeaderValues.elementAt(i);
00538 }
00539
00540 public Enumeration getHeaderNames() {
00541 return reqHeaderNames.elements();
00542 }
00543
00544 public Enumeration getHeaders(String header) {
00545 Vector result = new Vector();
00546 int i = -1;
00547 while ((i = reqHeaderNames.indexOf(header.toLowerCase(), i + 1)) >= 0)
00548 result.addElement(reqHeaderValues.elementAt(i));
00549 return result.elements();
00550 }
00551
00553
00554
00555 public ServletInputStream getInputStream() throws IOException {
00556 synchronized (in) {
00557 if (((ServeInputStream) in).isReturnedAsReader())
00558 throw new IllegalStateException("Already returned as a reader.");
00559 ((ServeInputStream) in).setReturnedAsReader(true);
00560 }
00561 return in;
00562 }
00563
00565
00566 public int getIntHeader(String name) {
00567 String val = getHeader(name);
00568 if (val == null)
00569 return -1;
00570
00571
00572
00573
00574 return Integer.parseInt(val);
00575 }
00576
00587 public String getLocalAddr() {
00588 return null;
00589 }
00590
00591
00592 public Enumeration getLocales() {
00593
00594
00595 return null;
00596 }
00597
00607 public String getLocalName() {
00608 return null;
00609 }
00610
00619 public int getLocalPort() {
00620 return webserver.port;
00621 }
00622
00623 public String getMethod() {
00624 return reqMethod;
00625 }
00626
00628
00629
00630 public String getParameter(String name) {
00631 String[] params = getParameterValues(name);
00632 if (params == null || params.length == 0)
00633 return null;
00634
00635 return params[0];
00636 }
00637
00647 public java.util.Map getParameterMap() {
00648 return (java.util.Map) formParameters;
00649 }
00650
00652 public Enumeration getParameterNames() {
00653 if (formParameters == null)
00654 formParameters = getParametersFromRequest();
00655 return formParameters.keys();
00656 }
00657
00659
00660 public String[] getParameterValues(String name) {
00661 if (formParameters == null)
00662 getParameterNames();
00663
00664 return (String[]) formParameters.get(name);
00665 }
00666
00667 public String getPathInfo() {
00668
00669
00670
00671 return uriLen >= reqUriPath.length() ? null : reqUriPath.substring(uriLen);
00672 }
00673
00674 public String getPathTranslated() {
00675
00676
00677
00678 return getRealPath(getPathInfo());
00679 }
00680
00682
00683
00684 public String getProtocol() {
00685 return reqProtocol;
00686 }
00687
00688
00689
00690 public String getQueryString() {
00691 return reqQuery;
00692 }
00693
00695
00696
00697
00698 public BufferedReader getReader() throws IOException {
00699 synchronized (in) {
00700 if (((ServeInputStream) in).isReturnedAsStream())
00701 throw new IllegalStateException("Already returned as a stream.");
00702 ((ServeInputStream) in).setReturnedAsStream(true);
00703 }
00704 if (reqCharEncoding != null)
00705 try {
00706 return new BufferedReader(new InputStreamReader(in, reqCharEncoding));
00707 } catch (UnsupportedEncodingException uee) {
00708 }
00709 return new BufferedReader(new InputStreamReader(in));
00710 }
00711
00713
00714
00715
00716
00717
00718 public String getRealPath(String path) {
00719 return webserver.getRealPath(path);
00720 }
00721
00723
00724 public String getRemoteAddr() {
00725 return socket.getInetAddress().getHostAddress().toString();
00726 }
00727
00729
00730
00731 public String getRemoteHost() {
00732 String result = socket.getInetAddress().getHostName();
00733 return result != null ? result : getRemoteAddr();
00734 }
00735
00744 public int getRemotePort() {
00745
00746 return webserver.port;
00747 }
00748
00750
00751 public String getRemoteUser() {
00752
00753 return null;
00754 }
00755
00756 public RequestDispatcher getRequestDispatcher(String urlpath) {
00757
00758 return null;
00759 }
00760
00761 public String getRequestedSessionId() {
00762
00763 return this.getSession().getId();
00764 }
00765
00766 public String getRequestURI() {
00767 return reqUriPath;
00768 }
00769
00770 public StringBuffer getRequestURL() {
00771 return new StringBuffer().append(getScheme()).append("://").append(this.getServerName())
00772 .append(webserver.port == 80 ? "" : ":"+String.valueOf(webserver.port)).append(getRequestURI());
00773 }
00774
00776
00777
00778
00779
00780 public String getScheme() {
00781 if (socket.getClass().getName().toUpperCase().indexOf("SSL") < 0)
00782 return "http";
00783 else
00784 return "https";
00785 }
00786
00788
00789
00790 public String getServerName() {
00791 String serverName;
00792 int serverPort = 80;
00793 serverName = getHeader("Host");
00794 if (serverName != null && serverName.length() > 0) {
00795 int colon = serverName.indexOf(':');
00796 if (colon >= 0) {
00797 if (colon < serverName.length())
00798 serverPort = Integer.parseInt(serverName.substring(colon + 1));
00799 serverName = serverName.substring(0, colon);
00800 }
00801 }
00802
00803 if (serverName == null) {
00804 try {
00805 serverName = InetAddress.getLocalHost().getHostName();
00806 } catch (java.net.UnknownHostException ignore) {
00807 serverName = "127.0.0.0";
00808 }
00809 }
00810
00811 int slash = serverName.indexOf("/");
00812 if (slash >= 0)
00813 serverName = serverName.substring(slash + 1);
00814 return serverName;
00815 }
00816
00818
00819
00820 public int getServerPort() {
00821 return socket.getLocalPort();
00822 }
00823
00824 public String getServletPath() {
00825
00826
00827
00828 return uriLen > 0 ? reqUriPath.substring(0, uriLen) : "";
00829 }
00830
00831 public HttpSession getSession() {
00832 return this.getSession(true);
00833 }
00834
00835 public HttpSession getSession(boolean create) {
00836
00837 SessionContext session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00838 if (session == null) {
00839 synchronized (SessionContextManager.getManager()) {
00840 session = SessionContextManager.getManager().getSessionContext("OPENMOBILEISSESSION");
00841 if (session == null) {
00842 session = SessionContextManager.getManager().createSessionContext("OPENMOBILEISSESSION");
00843 }
00844 }
00845 }
00846 SessionContextManager.getManager().joinSessionContext(session.getId());
00847 return SessionContextManager.getManager().getSessionContext();
00848 }
00849
00850 public Principal getUserPrincipal() {
00851
00852 return null;
00853 }
00854
00855 public boolean isRequestedSessionIdFromCookie() {
00856
00857 return false;
00858 }
00859
00860 public boolean isRequestedSessionIdFromURL() {
00861
00862 return false;
00863 }
00864
00865 public boolean isRequestedSessionIdFromUrl() {
00866
00867 return false;
00868 }
00869
00870 public boolean isRequestedSessionIdValid() {
00871 HttpSession session = this.getSession();
00872 if (session != null) {
00873 return true;
00874 }
00875 return false;
00876 }
00877
00878 public boolean isSecure() {
00879 return false;
00880 }
00881
00882 public boolean isUserInRole(String arg0) {
00883
00884 return false;
00885 }
00886
00887 public void removeAttribute(String name) {
00888
00889 }
00890
00891 public void setAttribute(String key, Object o) {
00892 attributes.put(key, o);
00893 }
00894
00902 public void setCharacterEncoding(String _enc) {
00903 reqCharEncoding = _enc;
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00924
00925
00926
00927 public String getCharacterEncoding() {
00928 String ct = (String) resHeaderNames.get(CONTENTTYPE);
00929 if (ct != null) {
00930 int scp = ct.indexOf(';');
00931 if (scp > 0) {
00932 scp = ct.toLowerCase().indexOf("charset=", scp);
00933 if (scp >= 0) {
00934 ct = ct.substring(scp + 8);
00935 scp = ct.indexOf(' ');
00936 if (scp > 0)
00937 ct = ct.substring(0, scp);
00938 scp = ct.indexOf(';');
00939 if (scp > 0)
00940 ct = ct.substring(0, scp);
00941 return ct;
00942 }
00943 }
00944 }
00945 return null;
00946 }
00947
00948 public Locale getLocale() {
00949 return locale;
00950 }
00951
00952
00953
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
00984
00985 public void addCookie(Cookie cookie) {
00986
00987 }
00988
00989 public void addDateHeader(String header, long date) {
00990 addHeader(header, expdatefmt.format(new Date(date)));
00991 }
00992
00993 public void addHeader(String header, String value) {
00994 Object o = resHeaderNames.get(header);
00995 if (o == null)
00996 setHeader(header, value);
00997 else {
00998 if (o instanceof String[]) {
00999 String[] oldVal = (String[]) o;
01000 String[] newVal = new String[oldVal.length + 1];
01001 System.arraycopy(oldVal, 0, newVal, 0, oldVal.length);
01002 newVal[oldVal.length] = value;
01003 resHeaderNames.put(header, newVal);
01004 } else if (o instanceof String) {
01005 String[] newVal = new String[2];
01006 newVal[0] = (String) o;
01007 newVal[1] = value;
01008 resHeaderNames.put(header, newVal);
01009 } else
01010 throw new RuntimeException("Invalid content of header hash - "
01011 + o.getClass().getName());
01012 }
01013 }
01014
01015 public void addIntHeader(String header, int value) {
01016 addHeader(header, Integer.toString(value));
01017 }
01018
01020
01021 public boolean containsHeader(String name) {
01022 return resHeaderNames.contains(name);
01023 }
01024
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 public String encodeRedirectUrl(String url) {
01037 return url;
01038 }
01039
01040 public String encodeRedirectURL(String url) {
01041 return url;
01042 }
01043
01044
01045
01046
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 public String encodeUrl(String url) {
01058 return url;
01059 }
01060
01061
01062 public String encodeURL(String url) {
01063 return url;
01064 }
01065
01066
01067
01068 public void flushBuffer() {
01069 }
01070
01071 public int getBufferSize() {
01072 return 0;
01073 }
01074
01076 public ServletOutputStream getOutputStream() throws IOException {
01077 synchronized (out) {
01078 if (((ServeOutputStream) out).isReturnedAsWriter())
01079 throw new IllegalStateException("Already returned as a writer");
01080 ((ServeOutputStream) out).setReturnedAsStream(true);
01081 }
01082 return out;
01083 }
01084
01086
01087
01088
01089
01090
01091
01092 public PrintWriter getWriter() throws IOException {
01093 synchronized (out) {
01094 if (((ServeOutputStream) out).isReturnedAsStream())
01095 throw new IllegalStateException("Already was returned as servlet output stream");
01096 ((ServeOutputStream) out).setReturnedAsWriter(true);
01097 }
01098 String encoding = getCharacterEncoding();
01099 if (encoding != null) {
01100
01101 printWriter = new PrintWriter(new OutputStreamWriter(out, encoding));
01102 } else {
01103
01104 printWriter = new PrintWriter(out);
01105 }
01106 return printWriter;
01107 }
01108
01117
01118 public boolean isCommitted() {
01119 return headersWritten;
01120 }
01121
01128 public void reset() {
01129 if (!isCommitted()) {
01130 resHeaderNames.clear();
01131 } else
01132 throw new IllegalStateException("Header have already been committed.");
01133 }
01134
01135 public void resetBuffer() {
01136 throw new IllegalStateException("The method not implemented");
01137 }
01138
01140
01141
01142
01143 public void sendError(int resCode, String resMessage) throws IOException {
01144 setStatus(resCode, resMessage);
01145 realSendError();
01146 }
01147
01149
01150
01151
01152 public void sendError(int resCode) throws IOException {
01153 setStatus(resCode);
01154 realSendError();
01155 }
01156
01158
01159
01160
01161 public void sendRedirect(String location) throws IOException {
01162 if (isCommitted())
01163 throw new IllegalStateException(
01164 "Can not redirect, headers have been already written");
01165 synchronized (out) {
01166
01167 ((ServeOutputStream) out).setReturnedAsStream(true);
01168 ((ServeOutputStream) out).setReturnedAsWriter(true);
01169 }
01170 setHeader("Location", location);
01171 setStatus(SC_MOVED_TEMPORARILY);
01172 setContentType("text/html");
01173 StringBuffer sb = new StringBuffer(200);
01174 sb.append("<HTML><HEAD>" + "<TITLE>" + SC_MOVED_TEMPORARILY
01175 + " Moved</TITLE>" + "</HEAD><BODY BGCOLOR=\"#F1D0F2\">"
01176 + "<H2>" + SC_MOVED_TEMPORARILY + " Moved</H2>"
01177 + "This document has moved <a href=" + location + ">here.<HR>");
01178 Identification.writeAddress(sb);
01179 sb.append("</BODY></HTML>");
01180 setContentLength(sb.length());
01181
01182 out.print(sb.toString());
01183 out.flush();
01184 }
01185
01186
01187
01188 public void setBufferSize(int size) {
01189 }
01190
01192
01193 public void setContentLength(int length) {
01194 setIntHeader(CONTENTLENGTH, length);
01195 }
01196
01198
01199 public void setContentType(String type) {
01200 setHeader(CONTENTTYPE, type != null ? type : "Unknown");
01201 }
01202
01204
01205
01206 public void setDateHeader(String name, long value) {
01207 setHeader(name, expdatefmt.format(new Date(value)));
01208 }
01209
01211
01212
01213 public void setHeader(String name, String value) {
01214 resHeaderNames.put(name, value);
01215 }
01216
01218
01219
01220 public void setIntHeader(String name, int value) {
01221 setHeader(name, Integer.toString(value));
01222 }
01223
01232 public void setLocale(Locale locale) {
01233 this.locale = locale;
01234 }
01235
01237
01238 public void setStatus(int resCode) {
01239 switch (resCode) {
01240 case SC_CONTINUE:
01241 setStatus(resCode, "Continue");
01242 break;
01243 case SC_SWITCHING_PROTOCOLS:
01244 setStatus(resCode, "Switching protocols");
01245 break;
01246 case SC_OK:
01247 setStatus(resCode, "Ok");
01248 break;
01249 case SC_CREATED:
01250 setStatus(resCode, "Created");
01251 break;
01252 case SC_ACCEPTED:
01253 setStatus(resCode, "Accepted");
01254 break;
01255 case SC_NON_AUTHORITATIVE_INFORMATION:
01256 setStatus(resCode, "Non-authoritative");
01257 break;
01258 case SC_NO_CONTENT:
01259 setStatus(resCode, "No content");
01260 break;
01261 case SC_RESET_CONTENT:
01262 setStatus(resCode, "Reset content");
01263 break;
01264 case SC_PARTIAL_CONTENT:
01265 setStatus(resCode, "Partial content");
01266 break;
01267 case SC_MULTIPLE_CHOICES:
01268 setStatus(resCode, "Multiple choices");
01269 break;
01270 case SC_MOVED_PERMANENTLY:
01271 setStatus(resCode, "Moved permanentently");
01272 break;
01273 case SC_MOVED_TEMPORARILY:
01274 setStatus(resCode, "Moved temporarily");
01275 break;
01276 case SC_SEE_OTHER:
01277 setStatus(resCode, "See other");
01278 break;
01279 case SC_NOT_MODIFIED:
01280 setStatus(resCode, "Not modified");
01281 break;
01282 case SC_USE_PROXY:
01283 setStatus(resCode, "Use proxy");
01284 break;
01285 case SC_BAD_REQUEST:
01286 setStatus(resCode, "Bad request");
01287 break;
01288 case SC_UNAUTHORIZED:
01289 setStatus(resCode, "Unauthorized");
01290 break;
01291 case SC_PAYMENT_REQUIRED:
01292 setStatus(resCode, "Payment required");
01293 break;
01294 case SC_FORBIDDEN:
01295 setStatus(resCode, "Forbidden");
01296 break;
01297 case SC_NOT_FOUND:
01298 setStatus(resCode, "Not found");
01299 break;
01300 case SC_METHOD_NOT_ALLOWED:
01301 setStatus(resCode, "Method not allowed");
01302 break;
01303 case SC_NOT_ACCEPTABLE:
01304 setStatus(resCode, "Not acceptable");
01305 break;
01306 case SC_PROXY_AUTHENTICATION_REQUIRED:
01307 setStatus(resCode, "Proxy auth required");
01308 break;
01309 case SC_REQUEST_TIMEOUT:
01310 setStatus(resCode, "Request timeout");
01311 break;
01312 case SC_CONFLICT:
01313 setStatus(resCode, "Conflict");
01314 break;
01315 case SC_GONE:
01316 setStatus(resCode, "Gone");
01317 break;
01318 case SC_LENGTH_REQUIRED:
01319 setStatus(resCode, "Length required");
01320 break;
01321 case SC_PRECONDITION_FAILED:
01322 setStatus(resCode, "Precondition failed");
01323 break;
01324 case SC_REQUEST_ENTITY_TOO_LARGE:
01325 setStatus(resCode, "Request entity too large");
01326 break;
01327 case SC_REQUEST_URI_TOO_LONG:
01328 setStatus(resCode, "Request URI too large");
01329 break;
01330 case SC_UNSUPPORTED_MEDIA_TYPE:
01331 setStatus(resCode, "Unsupported media type");
01332 break;
01333 case SC_INTERNAL_SERVER_ERROR:
01334 setStatus(resCode, "Internal server error");
01335 break;
01336 case SC_NOT_IMPLEMENTED:
01337 setStatus(resCode, "Not implemented");
01338 break;
01339 case SC_BAD_GATEWAY:
01340 setStatus(resCode, "Bad gateway");
01341 break;
01342 case SC_SERVICE_UNAVAILABLE:
01343 setStatus(resCode, "Service unavailable");
01344 break;
01345 case SC_GATEWAY_TIMEOUT:
01346 setStatus(resCode, "Gateway timeout");
01347 break;
01348 case SC_HTTP_VERSION_NOT_SUPPORTED:
01349 setStatus(resCode, "HTTP version not supported");
01350 break;
01351 default:
01352 setStatus(resCode, "");
01353 break;
01354 }
01355 }
01356
01358
01359
01360 public void setStatus(int resCode, String resMessage) {
01361
01362
01363
01364 this.resCode = resCode;
01365 this.resMessage = resMessage;
01366 }
01367
01368
01369
01370
01371 }