annotate bindings/as3/ext/com/adobe/net/proxies/RFC2817Socket.as @ 770:c54bc2ffbf92 tip

update tags
author convert-repo
date Fri, 16 Dec 2011 11:34:01 +0000
parents 3a0b9700b3d2
children
rev   line source
mas01mj@732 1 /*
mas01mj@732 2 Copyright (c) 2008, Adobe Systems Incorporated
mas01mj@732 3 All rights reserved.
mas01mj@732 4
mas01mj@732 5 Redistribution and use in source and binary forms, with or without
mas01mj@732 6 modification, are permitted provided that the following conditions are
mas01mj@732 7 met:
mas01mj@732 8
mas01mj@732 9 * Redistributions of source code must retain the above copyright notice,
mas01mj@732 10 this list of conditions and the following disclaimer.
mas01mj@732 11
mas01mj@732 12 * Redistributions in binary form must reproduce the above copyright
mas01mj@732 13 notice, this list of conditions and the following disclaimer in the
mas01mj@732 14 documentation and/or other materials provided with the distribution.
mas01mj@732 15
mas01mj@732 16 * Neither the name of Adobe Systems Incorporated nor the names of its
mas01mj@732 17 contributors may be used to endorse or promote products derived from
mas01mj@732 18 this software without specific prior written permission.
mas01mj@732 19
mas01mj@732 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
mas01mj@732 21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
mas01mj@732 22 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
mas01mj@732 23 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
mas01mj@732 24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
mas01mj@732 25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
mas01mj@732 26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
mas01mj@732 27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
mas01mj@732 28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
mas01mj@732 29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
mas01mj@732 30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
mas01mj@732 31 */
mas01mj@732 32 package com.adobe.net.proxies
mas01mj@732 33 {
mas01mj@732 34 import flash.events.Event;
mas01mj@732 35 import flash.events.IOErrorEvent;
mas01mj@732 36 import flash.events.ProgressEvent;
mas01mj@732 37 import flash.net.Socket;
mas01mj@732 38
mas01mj@732 39 /**
mas01mj@732 40 * This class allows TCP socket connections through HTTP proxies in accordance with
mas01mj@732 41 * RFC 2817:
mas01mj@732 42 *
mas01mj@732 43 * ftp://ftp.rfc-editor.org/in-notes/rfc2817.txt
mas01mj@732 44 *
mas01mj@732 45 * It can also be used to make direct connections to a destination, as well. If you
mas01mj@732 46 * pass the host and port into the constructor, no proxy will be used. You can also
mas01mj@732 47 * call connect, passing in the host and the port, and if you didn't set the proxy
mas01mj@732 48 * info, a direct connection will be made. A proxy is only used after you have called
mas01mj@732 49 * the setProxyInfo function.
mas01mj@732 50 *
mas01mj@732 51 * The connection to and negotiation with the proxy is completely hidden. All the
mas01mj@732 52 * same events are thrown whether you are using a proxy or not, and the data you
mas01mj@732 53 * receive from the target server will look exact as it would if you were connected
mas01mj@732 54 * to it directly rather than through a proxy.
mas01mj@732 55 *
mas01mj@732 56 * @author Christian Cantrell
mas01mj@732 57 *
mas01mj@732 58 **/
mas01mj@732 59 public class RFC2817Socket
mas01mj@732 60 extends Socket
mas01mj@732 61 {
mas01mj@732 62 private var proxyHost:String = null;
mas01mj@732 63 private var host:String = null;
mas01mj@732 64 private var proxyPort:int = 0;
mas01mj@732 65 private var port:int = 0;
mas01mj@732 66 private var deferredEventHandlers:Object = new Object();
mas01mj@732 67 private var buffer:String = new String();
mas01mj@732 68
mas01mj@732 69 /**
mas01mj@732 70 * Construct a new RFC2817Socket object. If you pass in the host and the port,
mas01mj@732 71 * no proxy will be used. If you want to use a proxy, instantiate with no
mas01mj@732 72 * arguments, call setProxyInfo, then call connect.
mas01mj@732 73 **/
mas01mj@732 74 public function RFC2817Socket(host:String = null, port:int = 0)
mas01mj@732 75 {
mas01mj@732 76 super(host, port);
mas01mj@732 77 }
mas01mj@732 78
mas01mj@732 79 /**
mas01mj@732 80 * Set the proxy host and port number. Your connection will only proxied if
mas01mj@732 81 * this function has been called.
mas01mj@732 82 **/
mas01mj@732 83 public function setProxyInfo(host:String, port:int):void
mas01mj@732 84 {
mas01mj@732 85 this.proxyHost = host;
mas01mj@732 86 this.proxyPort = port;
mas01mj@732 87
mas01mj@732 88 var deferredSocketDataHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA];
mas01mj@732 89 var deferredConnectHandler:Object = this.deferredEventHandlers[Event.CONNECT];
mas01mj@732 90
mas01mj@732 91 if (deferredSocketDataHandler != null)
mas01mj@732 92 {
mas01mj@732 93 super.removeEventListener(ProgressEvent.SOCKET_DATA, deferredSocketDataHandler.listener, deferredSocketDataHandler.useCapture);
mas01mj@732 94 }
mas01mj@732 95
mas01mj@732 96 if (deferredConnectHandler != null)
mas01mj@732 97 {
mas01mj@732 98 super.removeEventListener(Event.CONNECT, deferredConnectHandler.listener, deferredConnectHandler.useCapture);
mas01mj@732 99 }
mas01mj@732 100 }
mas01mj@732 101
mas01mj@732 102 /**
mas01mj@732 103 * Connect to the specified host over the specified port. If you want your
mas01mj@732 104 * connection proxied, call the setProxyInfo function first.
mas01mj@732 105 **/
mas01mj@732 106 public override function connect(host:String, port:int):void
mas01mj@732 107 {
mas01mj@732 108 if (this.proxyHost == null)
mas01mj@732 109 {
mas01mj@732 110 this.redirectConnectEvent();
mas01mj@732 111 this.redirectSocketDataEvent();
mas01mj@732 112 super.connect(host, port);
mas01mj@732 113 }
mas01mj@732 114 else
mas01mj@732 115 {
mas01mj@732 116 this.host = host;
mas01mj@732 117 this.port = port;
mas01mj@732 118 super.addEventListener(Event.CONNECT, this.onConnect);
mas01mj@732 119 super.addEventListener(ProgressEvent.SOCKET_DATA, this.onSocketData);
mas01mj@732 120 super.connect(this.proxyHost, this.proxyPort);
mas01mj@732 121 }
mas01mj@732 122 }
mas01mj@732 123
mas01mj@732 124 private function onConnect(event:Event):void
mas01mj@732 125 {
mas01mj@732 126 this.writeUTFBytes("CONNECT "+this.host+":"+this.port+" HTTP/1.1\n\n");
mas01mj@732 127 this.flush();
mas01mj@732 128 this.redirectConnectEvent();
mas01mj@732 129 }
mas01mj@732 130
mas01mj@732 131 private function onSocketData(event:ProgressEvent):void
mas01mj@732 132 {
mas01mj@732 133 while (this.bytesAvailable != 0)
mas01mj@732 134 {
mas01mj@732 135 this.buffer += this.readUTFBytes(1);
mas01mj@732 136 if (this.buffer.search(/\r?\n\r?\n$/) != -1)
mas01mj@732 137 {
mas01mj@732 138 this.checkResponse(event);
mas01mj@732 139 break;
mas01mj@732 140 }
mas01mj@732 141 }
mas01mj@732 142 }
mas01mj@732 143
mas01mj@732 144 private function checkResponse(event:ProgressEvent):void
mas01mj@732 145 {
mas01mj@732 146 var responseCode:String = this.buffer.substr(this.buffer.indexOf(" ")+1, 3);
mas01mj@732 147
mas01mj@732 148 if (responseCode.search(/^2/) == -1)
mas01mj@732 149 {
mas01mj@732 150 var ioError:IOErrorEvent = new IOErrorEvent(IOErrorEvent.IO_ERROR);
mas01mj@732 151 ioError.text = "Error connecting to the proxy ["+this.proxyHost+"] on port ["+this.proxyPort+"]: " + this.buffer;
mas01mj@732 152 this.dispatchEvent(ioError);
mas01mj@732 153 }
mas01mj@732 154 else
mas01mj@732 155 {
mas01mj@732 156 this.redirectSocketDataEvent();
mas01mj@732 157 this.dispatchEvent(new Event(Event.CONNECT));
mas01mj@732 158 if (this.bytesAvailable > 0)
mas01mj@732 159 {
mas01mj@732 160 this.dispatchEvent(event);
mas01mj@732 161 }
mas01mj@732 162 }
mas01mj@732 163 this.buffer = null;
mas01mj@732 164 }
mas01mj@732 165
mas01mj@732 166 private function redirectConnectEvent():void
mas01mj@732 167 {
mas01mj@732 168 super.removeEventListener(Event.CONNECT, onConnect);
mas01mj@732 169 var deferredEventHandler:Object = this.deferredEventHandlers[Event.CONNECT];
mas01mj@732 170 if (deferredEventHandler != null)
mas01mj@732 171 {
mas01mj@732 172 super.addEventListener(Event.CONNECT, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference);
mas01mj@732 173 }
mas01mj@732 174 }
mas01mj@732 175
mas01mj@732 176 private function redirectSocketDataEvent():void
mas01mj@732 177 {
mas01mj@732 178 super.removeEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
mas01mj@732 179 var deferredEventHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA];
mas01mj@732 180 if (deferredEventHandler != null)
mas01mj@732 181 {
mas01mj@732 182 super.addEventListener(ProgressEvent.SOCKET_DATA, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference);
mas01mj@732 183 }
mas01mj@732 184 }
mas01mj@732 185
mas01mj@732 186 public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int=0.0, useWeakReference:Boolean=false):void
mas01mj@732 187 {
mas01mj@732 188 if (type == Event.CONNECT || type == ProgressEvent.SOCKET_DATA)
mas01mj@732 189 {
mas01mj@732 190 this.deferredEventHandlers[type] = {listener:listener,useCapture:useCapture, priority:priority, useWeakReference:useWeakReference};
mas01mj@732 191 }
mas01mj@732 192 else
mas01mj@732 193 {
mas01mj@732 194 super.addEventListener(type, listener, useCapture, priority, useWeakReference);
mas01mj@732 195 }
mas01mj@732 196 }
mas01mj@732 197 }
mas01mj@732 198 }