📄 serve.java
字号:
if (serve.isAccessLogged()) { serve.log(socket.getInetAddress().toString()+' '+reqMethod+' '+reqUriPath+' ' + resCode +(serve.isShowReferer()?"| "+getHeader("Referer"):"") +(serve.isShowUserAgent()?"| "+getHeader("User-Agent"):"") ); } try { socket.close(); } catch ( IOException e ) { /* ignore */ } } private void parseRequest() { byte[] lineBytes = new byte[4096]; int len; String line; try { // Read the first line of the request. len = in.readLine( lineBytes, 0, lineBytes.length ); if ( len == -1 || len == 0 ) { problem( "Empty request", SC_BAD_REQUEST ); return; } line = new String( lineBytes, 0, len ); StringTokenizer ust = new StringTokenizer( line ); reqProtocol = null; if (ust.hasMoreTokens()) { reqMethod = ust.nextToken(); if (ust.hasMoreTokens()) { reqUriPath = Acme.Utils.urlDecoder(ust.nextToken()); if (ust.hasMoreTokens()) { reqProtocol = ust.nextToken(); oneOne = ! reqProtocol.toUpperCase().equals( "HTTP/1.0" ); reqMime = true; // Read the rest of the lines. String s; while ((s=((ServeInputStream)in).readLine())!=null) { if (s.length()==0) break; int c = s.indexOf(':',0); if (c>0) { String key = s.substring(0,c).trim(); String value = s.substring(c+1,s.length()).trim(); reqHeaderNames.addElement( key.toLowerCase() ); reqHeaderValues.addElement( value ); } else serve.log("header field without ':'"); } } else { reqProtocol = "HTTP/0.9"; oneOne = false; reqMime = false; } } } if (reqProtocol == null) { problem( "Malformed request line", SC_BAD_REQUEST ); return; } // Check Host: header in HTTP/1.1 requests. if ( oneOne ) { String host = getHeader( "host" ); if ( host == null ) { problem( "Host header missing on HTTP/1.1 request", SC_BAD_REQUEST ); return; } } // Decode %-sequences. //reqUriPath = decode( reqUriPath ); // Split off query string, if any. int qmark = reqUriPath.indexOf( '?' ); if ( qmark > -1 ) { reqQuery = reqUriPath.substring( qmark + 1 ); reqUriPath = reqUriPath.substring( 0, qmark ); } if (CHUNKED.equals(getHeader(TRANSFERENCODING))) { setHeader(CONTENTLENGTH,null); ((ServeInputStream)in).chunking(true); } Object []os = serve.registry.get( reqUriPath ); if (os != null) { uriLen = ((Integer)os[1]).intValue(); runServlet( (HttpServlet) os[0] ); } } catch ( IOException e ) { problem( "Reading request: " + e.getMessage(), SC_BAD_REQUEST ); } } private void runServlet( HttpServlet servlete ) { // Set default response fields. setStatus( SC_OK ); setDateHeader( "Date", System.currentTimeMillis() ); setHeader( "Server", Serve.Identification.serverName + "/" + Serve.Identification.serverVersion ); setHeader( "MIME-Version", "1.0" ); try { parseCookies(); authenificate(); if (servlete instanceof SingleThreadModel) synchronized(servlete) { servlete.service( (ServletRequest)this, (ServletResponse)this ); } else servlete.service( (ServletRequest)this, (ServletResponse)this ); } catch ( IOException e ) { e.printStackTrace(); problem( "IO problem running servlet: " + e.toString(), SC_BAD_REQUEST ); } catch ( ServletException e ) { problem( "problem running servlet: " + e.toString(), SC_BAD_REQUEST ); } catch ( Exception e ) { problem( "unexpected problem running servlet: " + e.toString(), SC_INTERNAL_SERVER_ERROR ); e.printStackTrace(); } } private boolean authenificate() throws IOException { Object [] o = serve.realms.get(getPathInfo()); BasicAuthRealm realm = null; if (o == null) realm = (BasicAuthRealm)o[0]; String credentials = getHeader("Authorization"); if (credentials!=null) { credentials = credentials.substring(credentials.indexOf(' ')+1); try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); serve.base64Dec.decodeBuffer(new StringBufferInputStream(credentials), baos); credentials = baos.toString(); } catch(IOException e) { e.printStackTrace(); } int i = credentials.indexOf(':'); String user = credentials.substring(0,i); String password = credentials.substring(i+1); remoteUser = user; authType = "Basic"; // support only basic authenification if (realm == null) return true; String realPassword=(String)realm.get(user); System.err.println("User "+user+" Password "+password+" real "+realPassword); if (realPassword!=null && realPassword.equals(password)) return true; } if (realm == null) return true; setStatus(SC_UNAUTHORIZED); setHeader("WWW-Authenticate", "basic realm=\""+realm.name()+'"'); writeHeaders(); return false; } private void problem( String logMessage, int resCode ) { serve.log( logMessage ); try { sendError( resCode ); } catch ( IllegalStateException e ) { /* ignore */ } catch ( IOException e ) { /* ignore */ } } private String decode( String str ) { StringBuffer result = new StringBuffer(); int l = str.length(); for ( int i = 0; i < l; ++i ) { char c = str.charAt( i ); if ( c == '%' && i + 2 < l ) { char c1 = str.charAt( i + 1 ); char c2 = str.charAt( i + 2 ); if ( isHexit( c1 ) && isHexit( c2 ) ) { result.append( (char) ( hexit( c1 ) * 16 + hexit( c2 ) ) ); i += 2; } else result.append( c ); } else if ( c == '+') result.append( ' ' ); else result.append( c ); } return result.toString(); } private boolean isHexit( char c ) { String legalChars = "0123456789abcdefABCDEF"; return ( legalChars.indexOf( c ) != -1 ); } private int hexit( char c ) { if ( c >= '0' && c <= '9' ) return c - '0'; if ( c >= 'a' && c <= 'f' ) return c - 'a' + 10; if ( c >= 'A' && c <= 'F' ) return c - 'A' + 10; return 0; // shouldn't happen, we're guarded by isHexit() } void parseCookies() { if (inCookies == null) inCookies = new Vector(); try { String cookie_name; String cookie_value; String cookie_path; String cookies = getHeader(COOKIE); if (cookies == null) return; //Enumeration e = getHeaders(COOKIE); //while(e.hasMoreElements()) // cookies += (String)e.nextElement(); StringTokenizer st = new StringTokenizer(cookies, ";", true); // TODO: write a parser to avoid tokenizers while(st.hasMoreTokens()) { StringTokenizer st2 = new StringTokenizer(st.nextToken(), "="); if (st2.hasMoreTokens()) { cookie_name=st2.nextToken().trim(); if (st2.hasMoreTokens()) { cookie_value=st2.nextToken(",").trim(); if (cookie_value.length() > 0 && cookie_value.charAt(0) == '=') cookie_value = cookie_value.substring(1); cookie_path = "/"; while(st2.hasMoreTokens()) { String cookie_atr = st2.nextToken(); if ("$Version".equalsIgnoreCase(cookie_atr) || "$Path".equalsIgnoreCase(cookie_atr) || "$Domain".equalsIgnoreCase(cookie_atr)) continue; cookie_path = st2.nextToken(); } Cookie cookie = new Cookie(cookie_name, cookie_value); //System.err.println("Cookie set:"+cookie_name+':'+cookie_value); cookie.setPath(cookie_path); inCookies.addElement(cookie); if (SESSION_COOKIE_NAME.equals(cookie_name) && sessionCookieValue == null) { sessionCookieValue = cookie_value; try { ((AcmeSession)serve.getSession(sessionCookieValue)).userTouch(); } catch(Throwable t) { } } } } } } catch (Throwable e) { System.err.println("prepareCookies(): "+e); e.printStackTrace(); } } // Methods from ServletRequest. /// Returns the size of the request entity data, or -1 if not known. // Same as the CGI variable CONTENT_LENGTH. public int getContentLength() { return getIntHeader( CONTENTLENGTH, -1 ); } /// Returns the MIME type of the request entity data, or null if // not known. // Same as the CGI variable CONTENT_TYPE. public String getContentType() { return getHeader( CONTENTTYPE ); } /// Returns the protocol and version of the request as a string of // the form <protocol>/<major version>.<minor version>. // Same as the CGI variable SERVER_PROTOCOL. public String getProtocol() { return reqProtocol; } /// Returns the scheme of the URL used in this request, for example // "http", "https", or "ftp". Different schemes have different rules // for constructing URLs, as noted in RFC 1738. The URL used to create // a request may be reconstructed using this scheme, the server name // and port, and additional information such as URIs. public String getScheme() { if (socket.getClass().getName().toUpperCase().indexOf("SSL") < 0) return "http"; else return "https"; } /// Returns the host name of the server as used in the <host> part of // the request URI. // Same as the CGI variable SERVER_NAME. public String getServerName() { String serverName; int serverPort=80; serverName=getHeader("Host"); if (serverName!=null && serverName.length()>0) { int colon=serverName.indexOf(':'); if (colon>=0) { if (colon<serverName.length()) serverPort= Integer.parseInt(serverName.substring(colon+1)); serverName=serverName.substring(0,colon); } } if (serverName==null) { try {serverName=InetAddress.getLocalHost().getHostName();} catch(java.net.UnknownHostException ignore) { serverName="127.0.0.0"; } } int slash = serverName.indexOf("/"); if (slash>=0) serverName=serverName.substring(slash+1); return serverName; } /// Returns the port number on which this request was received as used in // the <port> part of the request URI. // Same as the CGI variable SERVER_PORT. public int getServerPort() { return socket.getLocalPort(); } /// Returns the IP address of the agent that sent the request. // Same as the CGI variable REMOTE_ADDR. public String getRemoteAddr() { return socket.getInetAddress().toString();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -