001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Mikhail A. Markov, Vasily Zakharov
021: * @version $Revision: 1.1.2.1 $
022: */package org.apache.harmony.rmi.transport.proxy;
023:
024: import java.io.BufferedInputStream;
025: import java.io.IOException;
026: import java.net.ServerSocket;
027: import java.net.Socket;
028:
029: import org.apache.harmony.rmi.common.RMILog;
030: import org.apache.harmony.rmi.internal.nls.Messages;
031: import org.apache.harmony.rmi.transport.SocketWrapper;
032:
033: /**
034: * HTTP server socket, detects connection type
035: * and forwards the HTTP requests to {@link HttpInboundSocket}.
036: *
037: * @author Mikhail A. Markov, Vasily Zakharov
038: * @version $Revision: 1.1.2.1 $
039: */
040: public class HttpServerSocket extends ServerSocket implements
041: ProxyConstants {
042:
043: /**
044: * Creates this socket bound to the specified port.
045: *
046: * @param port
047: * Port.
048: *
049: * @throws IOException
050: * If I/O error occurs.
051: */
052: public HttpServerSocket(int port) throws IOException {
053: super (port);
054: }
055:
056: /**
057: * Creates this socket bound to the specified port,
058: * with the specified backlog.
059: *
060: * @param port
061: * Port.
062: *
063: * @param backlog
064: * Backlog.
065: *
066: * @throws IOException
067: * If I/O error occurs.
068: */
069: public HttpServerSocket(int port, int backlog) throws IOException {
070: super (port, backlog);
071: }
072:
073: /**
074: * {@inheritDoc}
075: */
076: public Socket accept() throws IOException {
077: Socket s = super .accept();
078:
079: if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
080: // rmi.log.11F=Inbound connection from [{0}:{1}] to port {2} detected.
081: proxyTransportLog.log(RMILog.VERBOSE, Messages.getString(
082: "rmi.log.11F", //$NON-NLS-1$
083: new Object[] { s.getInetAddress().getHostName(),
084: s.getPort(), s.getLocalPort() }));
085: }
086:
087: // Detect if incoming request is using HTTP or direct socket.
088: //
089: // Note: here we ignore the following for simplicity:
090: // Ignore CRLF if it's present before the POST line.
091: // (See RFC 2616 4.1)
092: //
093: // Note: Theoretically, we SHOULD return
094: // the status code 501 (Not Implemented)
095: // if the method is not POST (the only method we support).
096: // (See RFC 2616 5.1.1)
097: // But we ignore this, since we need to fall back to direct
098: // connection if HTTP connection cannot be established.
099: BufferedInputStream in = new BufferedInputStream(s
100: .getInputStream());
101: byte[] buffer = new byte[HTTP_REQUEST_SIGNATURE_LENGTH];
102: in.mark(HTTP_REQUEST_SIGNATURE_LENGTH);
103:
104: // Use read(), not read(byte[], int, int)
105: // because we need a blocking read operation here.
106: for (int i = 0; i < HTTP_REQUEST_SIGNATURE_LENGTH; i++) {
107: int c = in.read();
108:
109: if (c < 0) {
110: break;
111: }
112: buffer[i] = (byte) c;
113: }
114: boolean isHttp = new String(buffer)
115: .equals(HTTP_REQUEST_SIGNATURE);
116: in.reset();
117:
118: if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
119: proxyTransportLog.log(RMILog.VERBOSE, Messages.getString(
120: "rmi.log.120", new String(buffer)));//$NON-NLS-1$
121: }
122:
123: if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
124: // rmi.log.121=Direct socket
125: // rmi.log.122= connection from [{0}:{1}] to port {2} detected.
126: proxyTransportLog.log(RMILog.VERBOSE,
127: (isHttp ? "HTTP" : Messages //$NON-NLS-1$
128: .getString("rmi.log.121")) //$NON-NLS-1$
129: + Messages.getString("rmi.log.122", //$NON-NLS-1$
130: new Object[] {
131: s.getInetAddress()
132: .getHostName(),
133: s.getPort(),
134: s.getLocalPort() }));
135: }
136:
137: // Direct socket must be wrapped to avoid losing already read data.
138: return (isHttp ? new HttpInboundSocket(s, in, null)
139: : new SocketWrapper(s, in, null));
140: }
141:
142: /**
143: * {@inheritDoc}
144: */
145: public String toString() {
146: return ("HttpServerSocket[" + super .toString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
147: }
148: }
|