mina_server

阅读更多
http协议header中,异步socket(nio、mina)中必须指定其Content-Length的长度,才算结束。

/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *  
 *    http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License. 
 *  
 */
package org.apache.mina.example.httpserver.stream;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.support.BaseByteBuffer;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.pica.common.CommonUtils;
import com.pica.config.Dispatch;
import com.pica.server.BaseAction;
import com.pica.server.Request;
import com.pica.server.action.FetchEventAction;

/**
 * A simplistic HTTP protocol handler that replies back the URL and headers
 * which a client requested.
 * 
 * @author The Apache Directory Project ([email protected])
 * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (Fri, 13 Jul 2007)
 *          $
 */
public class HttpProtocolHandler extends IoHandlerAdapter {

	private static final Logger Log = LoggerFactory.getLogger(HttpProtocolHandler.class);

	public void sessionOpened(IoSession session) throws Exception {
		Log.debug("ConnectionHandler: sessionOpened.");
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		Log.debug("ConnectionHandler: sessionClosed.");
	}

	/**
	 * Invoked when a MINA session has been idle for half of the allowed XMPP
	 * session idle time as specified by {@link #getMaxIdleTime()}. This method
	 * will be invoked each time that such a period passes (even if no IO has
	 * occurred in between).
	 * 
	 * Openfire will disconnect a session the second time this method is
	 * invoked, if no IO has occurred between the first and second invocation.
	 * This allows extensions of this class to use the first invocation to check
	 * for livelyness of the MINA session (e.g by polling the remote entity, as
	 * {@link ClientConnectionHandler} does).
	 * 
	 * 两次心跳时间内没有消息交互就断开连接
	 * 
	 * @see org.apache.mina.common.IoHandlerAdapter#sessionIdle(org.apache.mina.common.IoSession,
	 *      org.apache.mina.common.IdleStatus)
	 */
	@Override
	public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
		// Close idle connection
		Log.debug("ConnectionHandler:sessionIdle. Closing connection that has been idle: " + status);
	}

	@Override
	public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
		if (cause instanceof IOException) {
			Log.debug("ConnectionHandler: ", cause);
		} else if (cause instanceof ProtocolDecoderException) {
			Log.warn("Closing session due to exception: " + session, cause);
			session.close();
		} else {
			Log.error(cause.getMessage(), cause);
		}
	}

	public void messageReceived(IoSession session, Object message) throws Exception {
		super.messageReceived(session, message);
		Log.debug(session.hashCode() + ":" + this.hashCode() + ":messageReceived:" + message.getClass() + "\t" + message);
		org.apache.mina.common.support.BaseByteBuffer buffer = (org.apache.mina.common.support.BaseByteBuffer) message;
		
		InputStream in = buffer.asInputStream();
		String url;
		Map headers = new TreeMap();
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		int timeout = 0;
		StringBuffer sb = new StringBuffer();
		try {
			// Get request URL.
			url = br.readLine();
			if (url == null) {
				Log.debug("nowTime:"+new Date().getTime());
				Log.debug("getLastIoTime:"+session.getLastIoTime());
				Log.debug("getLastReadTime:"+session.getLastReadTime());
				Log.debug("getLastWriteTime:"+session.getLastWriteTime());
				return;
			}
			url = url.split(" ")[1];
			Log.debug("url:"+url);
			String baseUrl = CommonUtils.getBaseUrl(url);
			Log.debug("baseUrl:"+baseUrl);
			if(baseUrl.endsWith("/aim/fetchEvents")){
				baseUrl = "/aim/fetchEvents";
			}
			Map parameter = CommonUtils.getParameter(url);

			// Read header
			String line;
			while ((line = br.readLine()) != null && !line.equals("")) {
				String[] tokens = line.replaceAll(" ", "").split(":");
				headers.put(tokens[0], tokens[1]);
			}
			String zlass = Dispatch.getDispatch(baseUrl);
			if (zlass != null) {
				Object obj = Class.forName(zlass).newInstance();
				if (obj instanceof BaseAction) {
					BaseAction action = (BaseAction) obj;
					timeout = action.doGet(new Request(in, headers, parameter), sb);
				} else {
					String notfound = "Not Found

Error 500-class [" + zlass + "] not extends com.pica.server.BaseAction

"; sb.append("HTTP/1.0 500 Internal Server Error\n"); sb.append("Content_Type:text/html\n"); sb.append("Content-Length:"+notfound.getBytes().length+"\t"); sb.append("\r\n\r\n"); sb.append(notfound); return; } } else { String notfound = "Not Found

Error 404-file [" + url + "] not found

"; sb.append("HTTP/1.0 404 no found\n"); sb.append("Content_Type:text/html\n"); sb.append("Content-Length:"+notfound.getBytes().length+"\t"); sb.append("\r\n\r\n"); sb.append(notfound); return; } } catch (Exception e) { sb.append("HTTP/1.0 500 Internal Server Error\n"); sb.append("Content_Type:text/html\n"); sb.append("Content-Length:"+e.getMessage().getBytes().length+"\t"); sb.append("\r\n\r\n"); sb.append(e.getMessage()); } finally { //sb.append("\r\n\r\n"); if(timeout > 0){ try { Thread.sleep(timeout); } catch (InterruptedException e) { e.printStackTrace(); } } session.write(BaseByteBuffer.wrap(sb.toString().getBytes())); } } public void messageSent(IoSession session, Object message) throws Exception { super.messageSent(session, message); org.apache.mina.common.support.BaseByteBuffer buffer = (org.apache.mina.common.support.BaseByteBuffer) message; InputStream in = buffer.asInputStream(); byte[] b = new byte[in.available()]; in.read(b); Log.debug("###############################################################################################################"); Log.debug(session.hashCode() + ":" + this.hashCode() + ":messageSent:" + message.getClass() + "\t" + new String(b)); Log.debug("###############################################################################################################"); } }

你可能感兴趣的:(Content-Length,mina,header)