httpproxy.java

来自「用java实现的」· Java 代码 · 共 184 行

JAVA
184
字号
/*
* LumaQQ - Java QQ Client
*
* Copyright (C) 2004 luma <stubma@163.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.tsinghua.lumaqq.qq;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <pre>
 * Http代理实现类。如果程序使用HTTP代理,则只能采用TCP方式登录。并且在请求中
 * 需要连接TCP服务器的443端口
 * </pre>
 * 
 * @author 马若劼
 */
public class HttpProxy extends AbstractProxy {
    /** Log类 */
	private static final Log log = LogFactory.getLog(HttpProxy.class);
	
	/** 回复码 - 成功 */
	public static final String SUCCESS = "200";
	/** 回复码 - 需要验证 */
	public static final String NEED_AUTH = "407";
	
    /** 状态 - 无动作 */
    public static final int STATUS_NONE = 0;
    /** 状态 - 最初请求 */
    public static final int STATUS_INIT = 1;
    /** 状态 - 验证 */
    public static final int STATUS_AUTH = 2;
    /** 状态 - Ready */
    public static final int STATUS_READY = 3;
    
    /** 请求连接的HTTP请求的前面部分 */
    private static final byte[] CONNECT_BEGIN = "CONNECT ".getBytes();
    /** 请求连接的HTTP请求的后面部分 */
    private static final byte[] CONNECT_END = 
        (" HTTP/1.1\r\n" +
         "Accept: */*\r\n" +
         "Content-Type: text/html\r\n" +
         "Proxy-Connection: Keep-Alive\r\n" +
         "Content-length: 0\r\n\r\n").getBytes();
    
    /** 远程主机地址,这个可能是ip,也可能是域名 */
    protected byte[] remoteAddress;
    /** 当前状态 */
    protected int status;
    
    /**
     * 构造函数
     * @param porter
     */
    public HttpProxy(Porter porter, IProxyHandler handler) {
        super(porter, handler);
        status = STATUS_NONE;
    }
    
    /**
     * 构造函数,带验证参数
     * @param porter Porter类
     * @param u 用户名
     * @param p 密码
     */
    public HttpProxy(Porter porter, IProxyHandler handler, String u, String p) {
        this(porter, handler);
        if(u != null)
            username = u;
        if(p != null)
            password = p;
    }

    /* (non-Javadoc)
     * @see edu.tsinghua.lumaqq.qq.IProxy#init()
     */
    public void init() {
        if(connected) {
            // 构造请求连接包
	        buffer.clear();       
	        buffer.put(CONNECT_BEGIN)
	        	.put(remoteAddress)
	        	.put(CONNECT_END);
	        // 发送
	        buffer.flip();
	        send();
	        status = STATUS_INIT;   
        }        
    }   

    /**
     * 验证 
     */
    private void auth() {
        // TODO Auto-generated method stub
        
    }

    /* (non-Javadoc)
     * @see edu.tsinghua.lumaqq.qq.INIOHandler#processRead(java.nio.channels.SelectionKey)
     */
    public void processRead(SelectionKey sk) throws IOException, PacketParseException {
        // 接收数据
        receive();
        // 检查头部
        byte[] b = new byte[buffer.limit()];
        buffer.get(b);
        String response = new String(b);
        if(!response.startsWith("HTTP/1."))
            return;
        // 判断状态
        switch(status) {
            case STATUS_INIT:
                // 得到回复码
                String replyCode = response.substring(9, 12);
                if(SUCCESS.equals(replyCode)) {
                    /* 成功 */
                    log.debug("连接成功");
                    status = STATUS_READY;
                    handler.proxyReady(null);
                } else if(NEED_AUTH.equals(replyCode)) {
                    /* 需要验证 */
                    log.debug("需要验证");
                    auth();
                } else {
                    log.debug("未知的回复码");
                    handler.proxyError(new Exception("Unknown Reply Code"));
                }
                break;
            case STATUS_AUTH:
                break;
            default:
                break;
        }
    }

    /* (non-Javadoc)
     * @see edu.tsinghua.lumaqq.qq.INIOHandler#processWrite()
     */
    public void processWrite() throws IOException {
        if(connected) {
	        switch(status) {
	            case STATUS_NONE:
	            case STATUS_INIT:
	                init();
	                break;
	            case STATUS_AUTH:
	                auth();
	                break;
	            default:
	                break;
	        }                        
        }
    }
    
    /* (non-Javadoc)
     * @see edu.tsinghua.lumaqq.qq.IProxy#setServerAddress(java.net.InetSocketAddress)
     */
    public void setServerAddress(InetSocketAddress serverAddress) {
        super.setServerAddress(serverAddress);
        String s = serverAddress.getHostName() + ':' + QQ.QQ_HTTP_PORT;
        this.remoteAddress = s.getBytes();
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?