001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.example.proxy; 021 022import java.io.File; 023import java.io.FileOutputStream; 024import java.io.IOException; 025import java.nio.channels.FileChannel; 026 027import org.apache.mina.core.buffer.IoBuffer; 028import org.apache.mina.core.session.IdleStatus; 029import org.apache.mina.core.session.IoSession; 030import org.apache.mina.proxy.AbstractProxyIoHandler; 031import org.apache.mina.proxy.handlers.ProxyRequest; 032import org.apache.mina.proxy.handlers.http.HttpProxyConstants; 033import org.apache.mina.proxy.handlers.http.HttpProxyRequest; 034import org.apache.mina.proxy.handlers.socks.SocksProxyRequest; 035import org.apache.mina.proxy.session.ProxyIoSession; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039/** 040 * ClientSessionHandler.java - Client session handler for the mina proxy test class. 041 * 042 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 043 * @since MINA 2.0.0-M3 044 */ 045public class ClientSessionHandler extends AbstractProxyIoHandler { 046 private final static Logger logger = LoggerFactory 047 .getLogger(ClientSessionHandler.class); 048 049 /** 050 * The temporary file were the request result will be written. 051 */ 052 private File file; 053 054 /** 055 * NIO channel of the temporary file. 056 */ 057 private FileChannel wChannel; 058 059 /** 060 * The command to issue to the proxy. 061 */ 062 private String cmd; 063 064 public ClientSessionHandler(String cmd) { 065 this.cmd = cmd; 066 } 067 068 /** 069 * {@inheritDoc} 070 */ 071 @Override 072 public void sessionCreated(IoSession session) throws Exception { 073 logger.debug("CLIENT - Session created: " + session); 074 } 075 076 /** 077 * Sends the request to the proxy server when session is opened with 078 * the proxy. 079 */ 080 @Override 081 public void proxySessionOpened(IoSession session) throws Exception { 082 logger.debug("CLIENT - Session opened: " + session); 083 ProxyIoSession proxyIoSession = (ProxyIoSession) session 084 .getAttribute(ProxyIoSession.PROXY_SESSION); 085 if (proxyIoSession != null) { 086 ProxyRequest req = proxyIoSession.getRequest(); 087 088 byte[] c = null; 089 if (req instanceof SocksProxyRequest && cmd != null) { 090 logger.debug("Sending request to a SOCKS SESSION ..."); 091 c = cmd.getBytes(proxyIoSession.getCharsetName()); 092 } else if (req instanceof HttpProxyRequest 093 && ((HttpProxyRequest) req).getHttpVerb() == HttpProxyConstants.CONNECT) { 094 logger.debug("Sending request to a HTTP CONNECTED SESSION ..."); 095 c = (((HttpProxyRequest) req).toHttpString()) 096 .getBytes(proxyIoSession.getCharsetName()); 097 } 098 099 if (c != null) { 100 IoBuffer buf = IoBuffer.allocate(c.length); 101 buf.put(c); 102 buf.flip(); 103 session.write(buf); 104 } 105 } 106 } 107 108 /** 109 * Writes the request result to a temporary file. 110 */ 111 @Override 112 public void messageReceived(IoSession session, Object message) { 113 logger.debug("CLIENT - Message received: " + session); 114 IoBuffer buf = (IoBuffer) message; 115 116 try { 117 if (file == null) { 118 file = File.createTempFile("http", ".html"); 119 logger.info("Writing request result to " 120 + file.getAbsolutePath()); 121 wChannel = new FileOutputStream(file, false).getChannel(); 122 } 123 124 // Write the ByteBuffer contents; the bytes between the ByteBuffer's 125 // position and the limit is written to the file 126 wChannel.write(buf.buf()); 127 } catch (IOException e) { 128 //e.printStackTrace(); 129 } 130 } 131 132 /** 133 * Closes the temporary file if it was opened. 134 */ 135 @Override 136 public void sessionClosed(IoSession session) throws Exception { 137 logger.debug("CLIENT - Session closed - closing result file if open."); 138 // Close the file 139 if (wChannel != null) { 140 wChannel.close(); 141 } 142 } 143 144 /** 145 * {@inheritDoc} 146 */ 147 @Override 148 public void sessionIdle(IoSession session, IdleStatus status) 149 throws Exception { 150 if (session.isClosing()) { 151 return; 152 } 153 154 logger.debug("CLIENT - Session idle"); 155 } 156 157 /** 158 * {@inheritDoc} 159 */ 160 @Override 161 public void exceptionCaught(IoSession session, Throwable cause) { 162 logger.debug("CLIENT - Exception caught"); 163 //cause.printStackTrace(); 164 session.closeNow(); 165 } 166}