SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续
引言上一篇 《Socket与网站保密应用 (隐藏链接的视频下载)》大大咧咧地从 WEB 讲 Socket,再到 TCP/IP 等协议,又再讲到 Wireshark 如何抓IP包分析,最还要复习一下路由与网络的知识,真的涉及面太广了,只能蜻蜓点水一一带过,不过将多领域的知识串烧也是不错的,可以起到一个归纳的作用。这篇针对 Flash 来进行,写作思路以解决问题的过程行为线索。依次展示如何使用 Flex Air 的 ServerSocket 和 Socket 实现简化版本的 HTTP 服务器,以及如何加载外部的 SWF 文件并进行操作。 在 mplayer.swf 内部,使用 FlasCC 集成 C 代码做保护。使用了 Hessian 做对象序列化,Hessian是一个由Caucho Technology开发的轻量级二进制RPC协议。Hessian 自称为 binary web service protocol this.i2 = mstate.ebp + -96; this.i2 = this.i2 + 24; this.i11 = this.i2 + this.i12; this.i14 = this.i8; this.i15 = this.i13; memcpy(this.i11,this.i14,this.i15); mstate.esp = mstate.esp - 8; mstate.esp = mstate.esp - 4; this.start(); mstate.esp = mstate.esp + 8; this.i2 = this.i13 + 64; 由于没有完全掌握 FlasCC ,所以没有深入,这里路过一下了,还是从 SWF 载入流程出发。通过调试得到,mvplayer 的执行是从这里开始的 com.yinyuetai.mvplayer.player.InPlayer > Player。抓主线,理清了 videoId 是如何和视频信息关联的,主要代码贴一贴,有点长,但这部分是最小功能 F**K CODE 之前,来两张AOA福利滋润一下各位看官:)。 //com.yinyuetai.mvplayer.player.player extends Sprite implements IPlayer public function loadByVideoId(id:String) : void { var key:String = null; var url:String = null; var req:GetRequest = null; var cLoader:* = new CLibInit(); var cLib:* = cLoader.init(); var stamp:String = UTCDateCreator.utcfiveminute(); key = cLib.encode(":" + id + ":" + stamp + ":" + PlayerVersion.version); // cLib.encode(":2344403:4797398:1.8.2.2") => ee4fb9b09346bd933dd22e37fe978741 32Byte var reg:RegExp = /^(http://.*?)/.*/; if (ServiceConfig.GET_VIDEOINFO_URL.indexOf("http") >= 0) { url = ServiceConfig.GET_VIDEOINFO_URL; } else { url = RootReference.stage.loaderInfo.url.replace(reg,"$1") + ServiceConfig.GET_VIDEOINFO_URL; } req = new GetRequest(url); req.addEventListener(RequestEvent.RESPONSE,this.onAfterGetVideoInfo); req.doRequest({videoId:id,sc:key,t:stamp,v:PlayerVersion.version}); // http://www.yinyuetai.com/main/get-mv-info? // flex=true&sc=ee4fb9b09346bd933dd22e37fe978741&t=4797398&v=1.8.2.2&videoId=2344403 // Content-Type:binary/hessian; charset=UTF-8 // data["videoInfo"] as MvSiteVideoInfo; return; } private function onAfterGetVideoInfo(event:RequestEvent) : void { var videoInfo:MvSiteVideoInfo = null; var coreVInfo:CoreVideoInfo = null; var pe:PlayerEvent = null; var evInfo:ExVideoInfo = null; var listItem:PlaylistItem = null; var o:Object = event.responseData; var isNOK:Boolean = o["error"] as Boolean; var msg:String = o["message"] as String; if (!isNOK) { videoInfo = o["videoInfo"] as MvSiteVideoInfo; coreVInfo = videoInfo.coreVideoInfo; if (coreVInfo.error) { pe = new PlayerEvent(PlayerEvent.MVPLAYER_ERROR,coreVInfo.errorMsg); dispatchEvent(pe); } else { evInfo = new ExVideoInfo(videoInfo); this.config.exVideoInfo = evInfo; listItem = new PlaylistItem(); listItem.init(coreVInfo); this.load(listItem); this.model.config.setConfig(coreVInfo); } } else { pe = new PlayerEvent(PlayerEvent.MVPLAYER_ERROR,msg); dispatchEvent(pe); } return; } //com.yinyuetai.mvplayer.model.ExVideoInfo extends Object public var pageUrl:String; public var headImage:String; public var bigHeadImage:String; public function ExVideoInfo(o:Object) { var reg:RegExp = /^(http://.*?)/.*/; var srvURL:String = ServiceConfig.REMOTE_SERVER_URL; if (o.hasOwnProperty("bigHeadImage") && o["bigHeadImage"]) { if (o["bigHeadImage"].indexOf("http") < 0) { this.bigHeadImage = (srvURL.indexOf("http") < 0 ? (RootReference.stage.loaderInfo.url.replace(reg,"$1")) : ("")) + srvURL + StringUtil.trim(o["bigHeadImage"]); } else { this.bigHeadImage = StringUtil.trim(o["bigHeadImage"]); } } if (o.hasOwnProperty("pageUrl") && o["pageUrl"]) { this.pageUrl = o["pageUrl"].indexOf("http") < 0 ? (srvURL + StringUtil.trim(o["pageUrl"])) : (StringUtil.trim(o["pageUrl"])); } if (o.hasOwnProperty("headImage") && o["headImage"]) { this.headImage = o["headImage"].indexOf("http") < 0 ? (srvURL + StringUtil.trim(o["headImage"])) : (StringUtil.trim(o["headImage"])); } if (o.hasOwnProperty("secretKeyUri") && o["secretKeyUri"]) { ServiceConfig.secretKeyURL = o["secretKeyUri"]; } return; } //com.yinyuetai.flex.GetRequest extends RequestBase public function GetRequest(param1:String = null,param2:URLVariables = null,param3:IUpdatable = null,param4:IResponseDecoder = null) : void { super(URLRequestMethod.GET,param1,param2,param3,param4); return; } //com.yinyuetai.flex.RequestBase extends EventDispatcher private var _method:String; private var _url:String; private var _params:URLVariables; private var _updatable:IUpdatable; private var _decoder:IResponseDecoder; private static var _addFlexParam:Boolean = true; public function RequestBase(m:String,url:String,data:URLVariables = null,up:IUpdatable = null,deco:IResponseDecoder = null) : void { this._method = m; this._url = url; this._params = data; this._updatable = up; this._decoder = deco; } protected function onComplete(event:Event) : void { var requestEvent:RequestEvent; var responseData:Object; var event:* = event; var stream:* = event.target as URLStream; var buffer:* = new ByteArray(); var offset:uint; do { stream.readBytes(buffer,offset,stream.bytesAvailable); offset = offset + stream.bytesAvailable; var ba:int = stream.bytesAvailable; }while (ba > 0) stream.close(); if (!this._decoder) { this._decoder = new HessianDecoder(); } try { responseData = this._decoder.decode(buffer); if (this._updatable) { this._updatable.responseData = responseData; } requestEvent = new RequestEvent(RequestEvent.RESPONSE); requestEvent.responseData = responseData; dispatchEvent(requestEvent); } catch (ex:DecodeError) { requestEvent = new RequestEvent(RequestEvent.ERROR); requestEvent.errorMessage = ex.message; dispatchEvent(requestEvent); if (_updatable) { _updatable.error(ex.message); } } dispatchEvent(new RequestEvent(RequestEvent.END)); if (this._updatable) { this._updatable.end(); } return; }// end function //com.yinyuetai.mvplayer.utils.UTCDateCreator extends Object public static function get utcfiveminute() : String { var r:int = null; var d:Date = new Date(); r = int(d.getTime() / 300000).toString(); return r; } //?package com.yinyuetai.mvplayer.player.PlayerVersion extends Object static const VERSION:String = "1.8.2.2"; //com.yinyuetai.mvplayer.ServiceConfig extends Object public static const REMOTE_SERVER_URL:String = "http://www.yinyuetai.com"; public static const GET_VIDEOINFO_URL:String = REMOTE_SERVER_URL + "/main/get-mv-info"; public static var secretKeyURL:String; //com.yinyuetai.mvplayer.pojos.MvSiteVideoInfo extends Object public var coreVideoInfo:CoreVideoInfo; public var secretKeyUri:String; public var pageUrl:String; //com.yinyuetai.mvplayer.pojos.CoreVideoInfo extends Object public var artistIds:String = ""; public var artistNames:String = ""; public var headImage:String = ""; public var bigHeadImage:String = ""; public var duration:int = 0; public var error:Boolean = false; public var errorMsg:String = ""; public var like:Boolean = false; public var threeD:Boolean = false; public var videoId:int = 0; public var videoName:String = ""; public var videoUrlModels:Array = null; //com.yinyuetai.mvplayer.pojos.VideoUrlModel extends Object public var qualityLevelName:String; public var videoUrl:String; public var bitrateType:int; public var bitrate:int; public var sha1:String; public var fileSize:int; public var md5:String; 以上代码通过追踪 loadByVideoId,可以发现 RequestBase 这个很关键的类,它使用了 IResponseDecoder 接口,实现了对象的逆序列化,这个过程是 hessian 类包实现的功能,主要是使用 Hessian2Input.readObject(), hessian-flash-4_0-snap.swc 就是应现在使用的版本,如果使用低版本会不认识MAGIC 0x48: Error: unknown code: 0x48 H at hessian.io::Hessian2Inpu。 有了这些后面会比较好办,稍为花点心思。先来用 Loader 将 mvplayer.swf 加载往来,然后调用它的 loadByVideoId,所以只需要提供一个 ID 就可以得到连接信息了,一条含有 get-mv-info 的数据请求,FlasCC 的逆向也免了。当然,使用这种方法也面临两个难题: 1. 沙箱安全约束。 2. 本地加载时,不允许使用 allowDomain() 方法,所以需要以服务端加载。 因为沙箱安全约束,即使用加载 mvplayer.swf 也不能使它读取到 yinyuetai.com 服务器的数据,因为改变了 mvplayer.swf 的位置后,原来的 yinyuetai.com 已经变成第三方网站了,所以要在它身上取数据,就要通过 crossDomain.xml 策略文件来授权。这个授权有点问题, 我试了一下本地做了一个 hack 版本: <cross-domain-policy> <allow-access-from domain="*"/> </cross-domain-policy> 上面这个策略文件就是一个完全开放许可,我需要做的就是把本地 hosts 文件修改一下,加入下面一行: 127.0.0.1 ? www.yinyuetai.com再次调用 mvplayer.swf 时,它依然是从 www.yinyuetai.com 请求数据,只是这次它的请求被路由到了本地的环回接口,我只需做一个 HTTP 服务提供上面的策略文件即可以解决授权,当 mvpayer.swf 认为得到授权后,还需要它来获取数据,所以要再次修改 hosts 文件,去掉之前的修改内容,这样就麻烦是有点,不过它真的 WORKING 了! 退一步来考虑,可以不需要 mvplayer.swf 获取数据,只要得到它间接产生的数据链接即可以达到破解的目的了。于是,我做了一个通过 ServerSocket 实现的 HTTP 服务,mvplayer.swf 就从这个 HTTP 服务加载,然后就让它产生一个数据请求,我需要做的是捕捉这个即将产生异常的数据请求。可惜的是,通过全局异常捕捉可以处理文档类 Player 产生的异常,但进入到 RequestBase 类后,Flash UncaughtErrorEvents 全局异常处理就真的异常了,完全不工作。而且使用 AIR 运行时,根本连异常的警告窗都不弹出来,所以有用的数据连接完全处理不了: ========================================================================= Error #2044: Unhandled SecurityErrorEvent:. text=Error #2048: Security sandbox violation: http://127.0.0.1/mvplayer.swf cannot load data from http://www.yinyuetai.com/main/get-mv-info?flex=true&sc=54e4b6daef63eb263d80e97ae4bb775a&t=4797652&v=1.8.2.2&videoId=2344403. at com.yinyuetai.flex::RequestBase/doRequest() at com.yinyuetai.mvplayer.player::Player/loadByVideoId() at Main/parseCMD() at Main/doKeyUp() ========================================================================= 到这里,问题似乎变得更复杂了,难道非要走上抓 IP 包的不归路?好吧,看 TCPViewr 这个小工具是怎么做的,看看如何自己写代码做一个 Tiny Sniffer,这只能先想想的法子,基本上也是一条不归路吧,以后有空再去搞。先要以简单的方法来解决问题,想想,想想,再想想!真的还是有的,而且极为便利,可以说随手拈来。那就是让 mvplayer.swf 请求数据时,去本地的服务器取数据了,本地服务器最多就是产生一条 404 回复,因此就不会产生不可以处理的异常了,太好了,就这样干了,使用 Hex Workshop 来找找 www.yinyuetai.com 来改掉: ========================================================================= 00033F40 74 74 70 3A 2F 2F 70 70 6C 73 69 73 2E 63 68 69 ttp://pplsis.chi 00033F50 6E 61 63 61 63 68 65 2E 6E 65 74 2F 66 69 6C 65 nacache.net/file 00033F60 11 52 45 4D 4F 54 45 5F 53 45 52 56 45 52 5F 55 .REMOTE_SERVER_U 00033F70 52 4C 18 68 74 74 70 3A 2F 2F 31 32 37 2E 31 30 RL.http://127.10 00033F80 30 2E 31 30 30 2E 31 30 3A 38 30 18 52 45 4D 4F 0.100.10:80.REMO 00033F90 54 45 5F 53 54 41 54 49 43 5F 53 45 52 56 45 52 TE_STATIC_SERVER 00033FA0 5F 55 52 4C 18 68 74 74 70 3A 2F 2F 73 2E 63 2E _URL.http://s.c. =========================================================================看上的服务器已经变成 127.100.100.10:80 了,处理后让 YueTai VIP 跑跑看,我的小工具叫“月台微挨披”,list 是命令,输入命令 list ID 就获取对应 ID 的视频数据: ========================================================================= list 2344403 Parsing command: list 2344403 Parse request: GET /main/get-mv-info?flex=true&sc=57dc2e7b639a3d74f87a295f22abc04a&t=4797738&v=1.8.2.2&videoId=2344403 HTTP/1.1 GET: /main/get-mv-info?flex=true&sc=57dc2e7b639a3d74f87a295f22abc04a&t=4797738&v=1.8.2.2&videoId=2344403 parseVideo Info: http://www.yinyuetai.com/main/get-mv-info?flex=true&sc=57dc2e7b639a3d74f87a295f22abc04a&t=4797738&v=1.8.2.2&videoId=2344403 Length: 1753 Video info: [object Object] CoreVideoInfo: [object Object] videoUrlModels: [object Object],[object Object],[object Object] ========================================================================= 这个 ID 的节目是 AOA专访 - 王牌天使 怦然心动! 15/08/04。看到 videoUrlModels 成员对应出现了四个 Object,离成功就不远了,提取一个 VideoUrlModel 数据来观赏: ========================================================================= qualityLevelName:String "流畅" videoUrl:String "http://hc.yinyuetai.com/uploads/videos/common/3132014EF85A8CE3ADF791CC5E279802.flv?sc=8600027e500abf9b&br=779&vid=2344403&aid=30971&area=ML&vst=6" bitrateType:int 1 bitrate:int 779 sha1:String "b83ad22372f9522e4803e7c0cd370fad08ffb3bd" fileSize:int 53090582 md5:String "82878eee0fc9a36d41beadc4557f533b" =========================================================================考虑到我的代码伤害性较大,就不全贴了,这里取一段展示如何使用傅 URLStream 加载 Hessian 序列化数据,并进行逆向序列,然后还有通过 ServerSocket 和 Socket 实现只支持 GET 动作的超简版本 HTTP 服务器。 private function parseVideoInfo(msg:String,index:int):void { //get-mv-info var gmi:String = YYT + msg.substr(index); log("parseVideo Info: " + gmi); var req:URLRequest = new URLRequest(gmi); var lod:URLStream = new URLStream(); req.method = URLRequestMethod.GET; lod.addEventListener(Event.COMPLETE,doMVInfo); //lod.dataFormat = URLLoaderDataFormat.BINARY; lod.load(req); } private function doMVInfo(e:Event):void { var lod:URLStream = URLStream(e.target); var buf:ByteArray = new ByteArray(); log("Length: " + lod.bytesAvailable); var inf:Object = new Hessian2Input(lod).readObject(); if ( inf.videoInfo && !inf.error) { // inf.logined var mvInfo:MvInfoModel = MvInfoModel(inf.videoInfo); var vInfo:MvInfo = mvInfo.coreVideoInfo; var vModels:Array = vInfo.videoUrlModels; log("Video info: " + vInfo.artistNames + " - " + vInfo.videoName); var i:String,mb:int = 1024*1024; for ( i in vModels) { var v:VideoUrlModel = vModels[i]; log( v.qualityLevelName + " " +(v.fileSize / mb).toFixed(2) + "MB " + v.videoUrl); } } } 最后,下载器的功能就不做了,目标已经达成,就这样收工。程序输出效果如下: ====================================================================== list 2344403 Parsing command: list 2344403 Close client <127.0.0.1:55585>. connect to <127.0.0.1:55586> Parse request: GET /main/get-mv-info?flex=true&sc=2019a249b4fc9065dba9a05a794571e2&t=4797752&v=1.8.2.2&videoId=2344403 HTTP/1.1 GET: /main/get-mv-info?flex=true&sc=2019a249b4fc9065dba9a05a794571e2&t=4797752&v=1.8.2.2&videoId=2344403 parseVideo Info: http://www.yinyuetai.com/main/get-mv-info?flex=true&sc=2019a249b4fc9065dba9a05a794571e2&t=4797752&v=1.8.2.2&videoId=2344403 Length: 1753 Video info: STAR!调查团,AOA - AOA专访 - 王牌天使 怦然心动! 15/08/04 流畅 50.63MB http://hc.yinyuetai.com/uploads/videos/common/3132014EF85A8CE3ADF791CC5E279802.flv?sc=5514cfbb95a8d0cd&br=779&vid=2344403&aid=30971&area=ML&vst=6 高清 71.40MB http://hd.yinyuetai.com/uploads/videos/common/757B014EF85F24E2341DCCA341D31C53.flv?sc=affff575aed9948a&br=1099&vid=2344403&aid=30971&area=ML&vst=6 超清 203.08MB http://he.yinyuetai.com/uploads/videos/common/1816014EF85F24DBDDA5B109E2710BA3.flv?sc=56451050f885c3c0&br=3125&vid=2344403&aid=30971&area=ML&vst=6 会员 397.74MB http://sh.yinyuetai.com/uploads/videos/common/EF43014EF85F24D5360F07B4721B30D6.mp4?sc=9ef45657ec52ff16&br=6122&vid=2344403&aid=30971&area=ML&vst=6 ====================================================================== 微缩HTTP服务器实现
外部 SWF 文件加载,完成载入后 SWF成员就指向外部文件的文档类。
package { import flash.display.*; import flash.events.*; import flash.net.URLRequest; import flash.display.Loader; import flash.system.LoaderContext; import flash.system.ApplicationDomain; /** * ... * @author Jimbowhy */ public class ContextAgent extends EventDispatcher { public static const ON_INIT:String = "oninit"; public var SWF:Object; // This is the reference to the main class of swf file public var URL:String = "http://airdownload.adobe.com/air/browserapi/air.swf"; // localhost version is ok "http://localhost/JSocketSrv/bin/air.swf"); // local sanbox not allow use Security.allowDomain() // SecurityError: Error #3207: Application-sandbox content cannot access this feature. private var SWFLoader:Loader = new Loader(); // Used to load the SWF private var loaderContext:LoaderContext = new LoaderContext(); private var doInit:Function; public function ContextAgent(url:String,fun:Function):void { if ( fun!=null ) { addEventListener(ContextAgent.ON_INIT,fun); doInit = fun; } if( url ) load(url) } public function load(url:String):void { URL = url || URL; // Used to set the application domain loaderContext.applicationDomain = ApplicationDomain.currentDomain; SWFLoader.contentLoaderInfo.addEventListener(Event.INIT,onInit); SWFLoader.load(new URLRequest(URL),loaderContext); } private function onInit(e:Event):void { SWF = e.target.content; dispatchEvent( new Event(ON_INIT) ); if ( doInit!=null ) { removeEventListener(ContextAgent.ON_INIT,doInit); doInit = null; } } } }微版HTTP,实现 crossDomain.xml 分发,可以执行 HTTP GET 动作。 package { import flash.events.*; import flash.events.*; import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; import flash.net.*; import flash.utils.ByteArray; import flash.utils.setInterval; /** * ... * @author Jimbowhy */ public class HttpAgent extends EventDispatcher { public static const ON_MESSAGE:String = "onMessage"; public var message:String; private var sovsok:ServerSocket; private var sovsokSecu:ServerSocket; private var clients:Array = new Array(); private var HOST:String = "127.0.0.1" private var PORT:int = 80; private var portSecu:int = 843; private var crossDomain:String = "<policy-file-request/>"; private var crossDomainXML:String = "<cross-domain-policy><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>"; public function HttpAgent(host:String = "127.0.0.1",port:int = 80):void { HOST = host; PORT = port; log( "Do Invoke <host:port>".replace("host",HOST).replace("port",PORT) ); //new ContextAgent("http://localhost/JSocketSrv/bin/air.swf"); if ( !ServerSocket.isSupported ) { log("ServerSocket is not supported."); return; } if ( sovsok ) clearAll(); try{ sovsokSecu = new ServerSocket(); sovsokSecu.addEventListener(ServerSocketConnectEvent.CONNECT,doConnectSecurity); sovsokSecu.bind(portSecu,HOST); sovsokSecu.listen(); log("Bound Security Server to <VA:VB>".replace("VA",HOST).replace("VB",portSecu)); sovsok = new ServerSocket(); sovsok.addEventListener(ServerSocketConnectEvent.CONNECT,doConnect); //sovsok.addEventListener(Event.CLOSE,doSocketClose); sovsok.bind(PORT,HOST); log("Bound to <VA:VB>".replace("VA",PORT)); sovsok.listen(); }catch (e:Error) { log(e.getStackTrace()); } if ( !sovsok || !sovsok.bound ) { log("Fail to bounding,check host address and port:"+PORT+","+portSecu); } } private function clearAll():void { if ( sovsok.bound ) sovsok.close(); sovsok.removeEventListener(ServerSocketConnectEvent.CONNECT,doConnect); if ( sovsokSecu.bound ) sovsokSecu.close(); sovsokSecu.removeEventListener(ServerSocketConnectEvent.CONNECT,doConnectSecurity); var i:int; for (i = 0; i < clients.length; i++) { var s:Socket = Socket(clients[i]); s.removeEventListener(ProgressEvent.SOCKET_DATA,doSocketClient); s.removeEventListener(Event.CLOSE,doSocketClose); s.removeEventListener(DataEvent.DATA,doSocketXML); s.close(); } clients = new Array(); } private function doSocketClose(e:Event):void { var sok:Socket = Socket(e.target); var s:Socket ; var c:Array = new Array(); while ( s = clients.shift() ) { if ( s != sok ) c.push(s); s.removeEventListener(ProgressEvent.SOCKET_DATA,doSocketClient); s.removeEventListener(DataEvent.DATA,doSocketXML); s.removeEventListener(Event.CLOSE,doSocketClose); log(" Close client <VA:VB>.".replace("VA",s.remoteAddress).replace("VB",s.remotePort) ); } } private function doConnectSecurity(e:ServerSocketConnectEvent):void { var policier:Socket = e.socket; policier.addEventListener(ProgressEvent.SOCKET_DATA,doSocketDataSecu); log( " Policier connected via port VA.".replace("VA",portSecu) ); } private function doConnect(e:ServerSocketConnectEvent):void { var client:Socket = e.socket; var msg:String = e.type + " to <VA:VB>"; log( msg.replace("VA",client.remoteAddress).replace("VB",client.remotePort) ); clients.push(client); client.addEventListener( ProgressEvent.SOCKET_DATA,doSocketClient ); //client.addEventListener( DataEvent.DATA,doSocketXML ); client.addEventListener( Event.CLOSE,doSocketClose ); } private function bin2hex(bytes:ByteArray):String { bytes.position = 0; var r:String = ""; var i:int; for (i = 0; i < 0x10; i++) r += "0x0" + i.toString(16)+" "; r += "n"; for (i = 0; i < bytes.length; i++) { var v:int = bytes.readByte(); r += (v>0x0F? "0x":"0x0") + v.toString(16)+" "; } return r; } private function doSocketClient(e:ProgressEvent):void { var sok:Socket = Socket(e.target); var buf:ByteArray = new ByteArray(); var len:int = e.bytesLoaded; sok.readBytes(buf,len); var txt:String = buf.readUTFBytes(len); while( txt.length<len){ // skip between XMLSocket send txt += buf.readUTFBytes(buf.bytesAvailable); txt += "n"; buf.position = txt.length; } trace( "Bin2Hex:n" + bin2hex(buf) ); //if(txt.length>512) txt = "..."; var msg:String = "Socket cient <VA:VB> " + txt.length + " " + e.bytesLoaded + "/" + e.bytesTotal + " :" + txt; //log( msg.replace("VA",sok.remoteAddress).replace("VB",sok.remotePort) ); if ( txt == crossDomain ) { responsePolicier(sok); trace("Response with crossDomain.xml"); }else { parseRequest(sok,txt); } } private function parseRequest(sok:Socket,req:String):void { var ls:Array = req.split("n"); log("Parse request: " + ls[0]); var r:Array = HTTP1P1.RGET.exec(ls[0]); if ( r ) { log("GET: " + r[2]); http_get(sok,r[2],req); }else { log(HTTP1P1.HTTP501+": " + ls[0]); sok.writeUTFBytes(HTTP1P1.HTTP501); sok.writeUTFBytes(HTTP1P1.HEADSPLITER); sok.flush(); } } private function http_get(sok:Socket,path:String,req:String):void { path = File.applicationDirectory.resolvePath("./"+path).nativePath; var file:File = new File(path); if ( !file.exists ) { log( HTTP1P1.HTTP404 + path); HTTP1P1.setHttpStatus(sok,404); HTTP1P1.setContentLength(sok,0); HTTP1P1.setMime(sok,"html"); HTTP1P1.setServerMark(sok); HTTP1P1.setHeaderFinish(sok); }else{ var buff:ByteArray = new ByteArray(); var stem:FileStream = new FileStream(); log("HTTP GET: " + path); stem.open(file,FileMode.READ); stem.readBytes(buff); HTTP1P1.setHttpStatus(sok,200); //HTTP1P1.setHeader(sok,"Content-Encoding","gzip"); HTTP1P1.setServerMark(sok); log( HTTP1P1.setMime(sok,file.extension) ); HTTP1P1.setContentLength(sok,buff.length); HTTP1P1.setHeaderFinish(sok); sok.writeBytes(buff); } sok.flush(); } private function doSocketXML(e:DataEvent):void { var sok:Socket = Socket(e.target); var txt:String = sok.readUTFBytes(sok.bytesAvailable); var msg:String = "XMLSocket cient <VA:VB> " + sok.bytesAvailable +" :" + txt; log( msg.replace("VA",sok.remotePort) ); if ( txt == crossDomain ) responsePolicier(sok); } private function doSocketDataSecu(e:ProgressEvent):void { var msg:String = "Security server receiving (VA)"; trace(msg.replace("VA",e.bytesLoaded)); //e.bytesTotal alway 0 for Socket var policier:Socket = Socket( e.target ); var req:String = policier.readUTFBytes(policier.bytesAvailable); trace("Policier request: " + req); if ( req == crossDomain ) responsePolicier(policier); policier.close(); } public function responsePolicier(policier:Socket):void { trace("Response: " + crossDomainXML); policier.writeUTFBytes( crossDomainXML ); policier.writeByte(0); // for XMLSocket policy policier.flush(); } private function log(msg:String):void { message = msg+("n"); var e:Event = new Event(HttpAgent.ON_MESSAGE); dispatchEvent(e); } } } HTTP1P1 类文件,保存HTTP状态常数,实现基础方法。 package { import flash.net.Socket; /** * ... * @author Jimbowhy */ public class HTTP1P1 { public static const HTTP200:String = "HTTP/1.1 200 OKrn"; public static const HTTP201:String = "HTTP/1.1 201 Createdrn"; public static const HTTP202:String = "HTTP/1.1 202 Acceptedrn"; public static const HTTP203:String = "HTTP/1.1 203 Non-Authoritative Informationrn"; public static const HTTP204:String = "HTTP/1.1 204 No Contentrn"; public static const HTTP205:String = "HTTP/1.1 205 Reset Contentrn"; public static const HTTP206:String = "HTTP/1.1 206 Partial Contentrn"; public static const HTTP300:String = "HTTP/1.1 300 Multiple Choicesrn"; public static const HTTP301:String = "HTTP/1.1 301 Moved Permanentlyrn"; public static const HTTP302:String = "HTTP/1.1 302 Foundrn"; public static const HTTP303:String = "HTTP/1.1 303 See Otherrn"; public static const HTTP304:String = "HTTP/1.1 304 Not Modifiedrn"; public static const HTTP305:String = "HTTP/1.1 305 Use Proxyrn"; public static const HTTP306:String = "HTTP/1.1 306 (Unused)rn"; public static const HTTP307:String = "HTTP/1.1 307 Temporary Redirectrn"; public static const HTTP400:String = "HTTP/1.1 400 Bad Requestrn"; public static const HTTP401:String = "HTTP/1.1 401 Unauthorizedrn"; public static const HTTP402:String = "HTTP/1.1 402 Payment Requiredrn"; public static const HTTP403:String = "HTTP/1.1 403 Forbiddenrn"; public static const HTTP404:String = "HTTP/1.1 404 Not Foundrn"; public static const HTTP405:String = "HTTP/1.1 405 Method Not Allowedrn"; public static const HTTP406:String = "HTTP/1.1 406 Not Acceptablern"; public static const HTTP407:String = "HTTP/1.1 407 Proxy Authentication Requiredrn"; public static const HTTP408:String = "HTTP/1.1 408 Request Timeoutrn"; public static const HTTP409:String = "HTTP/1.1 409 Conflictrn"; public static const HTTP410:String = "HTTP/1.1 410 Gonern"; public static const HTTP411:String = "HTTP/1.1 411 Length Requiredrn"; public static const HTTP412:String = "HTTP/1.1 412 Precondition Failedrn"; public static const HTTP413:String = "HTTP/1.1 413 Request Entity Too Largern"; public static const HTTP414:String = "HTTP/1.1 414 Request-URI Too Longrn"; public static const HTTP415:String = "HTTP/1.1 415 Unsupported Media Typern"; public static const HTTP416:String = "HTTP/1.1 416 Requested Range Not Satisfiablern"; public static const HTTP417:String = "HTTP/1.1 417 Expectation Failedrn"; public static const HTTP500:String = "HTTP/1.1 500 Internal Server Errorrn"; public static const HTTP501:String = "HTTP/1.1 501 Not Implementedrn"; public static const HTTP502:String = "HTTP/1.1 502 Bad Gatewayrn"; public static const HTTP503:String = "HTTP/1.1 503 Service Unavailablern"; public static const HTTP504:String = "HTTP/1.1 504 Gateway Timeoutrn"; public static const HTTP505:String = "HTTP/1.1 505 HTTP Version Not Supportedrn"; public static const HTTP520:String = "HTTP/1.1 520 Error setHttpStatus VArn"; public static const ContentLength:String = "Content-Length: VArn"; public static const HEADSPLITER:String = "rn"; public static const RGET:RegExp = /^(GET) (.+) (HTTP/1.1)$/; public static const SERVER:String = "Server: ServerSocket by Jimbowhyrn"; public static function setHeader(sok:Socket,name:String,value:String):void { sok.writeUTFBytes(name + ": " + value + "rn"); } public static function setHttpStatus(sok:Socket,statusCode:int):void { var s:String = HTTP1P1["HTTP" + statusCode]; if ( s == null) { sok.writeUTFBytes( HTTP520.replace("VA",statusCode) ); return; } sok.writeUTFBytes( s ); } public static function setServerMark(sok:Socket):void { sok.writeUTFBytes(SERVER); } public static function setMime(sok:Socket,ext:String):String { var ex:String = ext.split(".").pop(); var m:String = Mime["M_" + ex.toLowerCase()]; if ( m == null ) m = Mime.M_BIN; sok.writeUTFBytes("Content-Type: "+m); return m; } public static function setContentLength(sok:Socket,len:int):void { sok.writeUTFBytes(ContentLength.replace("VA",len)); } public static function setHeaderFinish(sok:Socket):void { sok.writeUTFBytes(HEADSPLITER); } } }Mime 类,记录文件相关的 MIME信息 package { /** * ... * @author Jimbowhy */ public class Mime { public static const M_001:String = "application/x-001rn"; public static const M_301:String = "application/x-301rn"; public static const M_323:String = "text/h323rn"; public static const M_906:String = "application/x-906rn"; public static const M_907:String = "drawing/907rn"; public static const M_BIN:String = "application/octet-streamrn"; public static const M_IVF:String = "video/x-ivfrn"; public static const M_a11:String = "application/x-a11rn"; public static const M_acp:String = "audio/x-mei-aacrn"; public static const M_ai:String = "application/postscriptrn"; public static const M_aif:String = "audio/aiffrn"; public static const M_aifc:String = "audio/aiffrn"; public static const M_aiff:String = "audio/aiffrn"; public static const M_anv:String = "application/x-anvrn"; public static const M_apk:String = "application/vnd.android.package-archivern"; public static const M_asa:String = "text/asarn"; public static const M_asf:String = "video/x-ms-asfrn"; public static const M_asp:String = "text/asprn"; public static const M_asx:String = "video/x-ms-asfrn"; public static const M_au:String = "audio/basicrn"; public static const M_avi:String = "video/avirn"; public static const M_awf:String = "application/vnd.adobe.workflowrn"; public static const M_biz:String = "text/xmlrn"; public static const M_bmp:String = "application/x-bmprn"; public static const M_bot:String = "application/x-botrn"; public static const M_c4t:String = "application/x-c4trn"; public static const M_c90:String = "application/x-c90rn"; public static const M_cal:String = "application/x-calsrn"; public static const M_cat:String = "application/vnd.ms-pki.seccatrn"; public static const M_cdf:String = "application/x-netcdfrn"; public static const M_cdr:String = "application/x-cdrrn"; public static const M_cel:String = "application/x-celrn"; public static const M_cer:String = "application/x-x509-ca-certrn"; public static const M_cg4:String = "application/x-g4rn"; public static const M_cgm:String = "application/x-cgmrn"; public static const M_cit:String = "application/x-citrn"; public static const M_class:String = "java/*rn"; public static const M_cml:String = "text/xmlrn"; public static const M_cmp:String = "application/x-cmprn"; public static const M_cmx:String = "application/x-cmxrn"; public static const M_cot:String = "application/x-cotrn"; public static const M_crl:String = "application/pkix-crlrn"; public static const M_crt:String = "application/x-x509-ca-certrn"; public static const M_csi:String = "application/x-csirn"; public static const M_css:String = "text/cssrn"; public static const M_cut:String = "application/x-cutrn"; public static const M_dbf:String = "application/x-dbfrn"; public static const M_dbm:String = "application/x-dbmrn"; public static const M_dbx:String = "application/x-dbxrn"; public static const M_dcd:String = "text/xmlrn"; public static const M_dcx:String = "application/x-dcxrn"; public static const M_der:String = "application/x-x509-ca-certrn"; public static const M_dgn:String = "application/x-dgnrn"; public static const M_dib:String = "application/x-dibrn"; public static const M_dll:String = "application/x-msdownloadrn"; public static const M_doc:String = "application/mswordrn"; public static const M_dot:String = "application/mswordrn"; public static const M_drw:String = "application/x-drwrn"; public static const M_dtd:String = "text/xmlrn"; //public static const M_dwf:String = "Model/vnd.dwfrn"; public static const M_dwf:String = "application/x-dwfrn"; public static const M_dwg:String = "application/x-dwgrn"; public static const M_dxb:String = "application/x-dxbrn"; public static const M_dxf:String = "application/x-dxfrn"; public static const M_edn:String = "application/vnd.adobe.ednrn"; public static const M_emf:String = "application/x-emfrn"; public static const M_eml:String = "message/rfc822rn"; public static const M_ent:String = "text/xmlrn"; public static const M_epi:String = "application/x-epirn"; public static const M_eps:String = "application/postscriptrn"; public static const M_etd:String = "application/x-ebxrn"; public static const M_exe:String = "application/x-msdownloadrn"; public static const M_fax:String = "image/faxrn"; public static const M_fdf:String = "application/vnd.fdfrn"; public static const M_fif:String = "application/fractalsrn"; public static const M_fo:String = "text/xmlrn"; public static const M_frm:String = "application/x-frmrn"; public static const M_g4:String = "application/x-g4rn"; public static const M_gbr:String = "application/x-gbrrn"; public static const M_gif:String = "image/gifrn"; public static const M_gl2:String = "application/x-gl2rn"; public static const M_gp4:String = "application/x-gp4rn"; public static const M_hgl:String = "application/x-hglrn"; public static const M_hmr:String = "application/x-hmrrn"; public static const M_hpg:String = "application/x-hpglrn"; public static const M_hpl:String = "application/x-hplrn"; public static const M_hqx:String = "application/mac-binhex40rn"; public static const M_hrf:String = "application/x-hrfrn"; public static const M_hta:String = "application/htarn"; public static const M_htc:String = "text/x-componentrn"; public static const M_htm:String = "text/htmlrn"; public static const M_html:String = "text/htmlrn"; public static const M_htt:String = "text/webviewhtmlrn"; public static const M_htx:String = "text/htmlrn"; public static const M_icb:String = "application/x-icbrn"; public static const M_ico:String = "application/x-icorn"; //public static const M_ico:String = "image/x-iconrn"; public static const M_iff:String = "application/x-iffrn"; public static const M_ig4:String = "application/x-g4rn"; public static const M_igs:String = "application/x-igsrn"; public static const M_iii:String = "application/x-iphonern"; public static const M_img:String = "application/x-imgrn"; public static const M_ins:String = "application/x-internet-signuprn"; public static const M_ipa:String = "application/vnd.iphonern"; public static const M_isp:String = "application/x-internet-signuprn"; public static const M_java:String = "java/*rn"; public static const M_jfif:String = "image/jpegrn"; //public static const M_jpe:String = "application/x-jpern"; public static const M_jpe:String = "image/jpegrn"; public static const M_jpeg:String = "image/jpegrn"; //public static const M_jpg:String = "application/x-jpgrn"; public static const M_jpg:String = "image/jpegrn"; public static const M_js:String = "application/x-javascriptrn"; public static const M_jsp:String = "text/htmlrn"; public static const M_la1:String = "audio/x-liquid-filern"; public static const M_lar:String = "application/x-laplayer-regrn"; public static const M_latex:String = "application/x-latexrn"; public static const M_lavs:String = "audio/x-liquid-securern"; public static const M_lbm:String = "application/x-lbmrn"; public static const M_lmsff:String = "audio/x-la-lmsrn"; public static const M_ls:String = "application/x-javascriptrn"; public static const M_ltr:String = "application/x-ltrrn"; public static const M_m1v:String = "video/x-mpegrn"; public static const M_m2v:String = "video/x-mpegrn"; public static const M_m3u:String = "audio/mpegurlrn"; public static const M_m4e:String = "video/mpeg4rn"; public static const M_mac:String = "application/x-macrn"; public static const M_man:String = "application/x-troff-manrn"; public static const M_math:String = "text/xmlrn"; //public static const M_mdb:String = "application/msaccessrn"; public static const M_mdb:String = "application/x-mdbrn"; public static const M_mfp:String = "application/x-shockwave-flashrn"; public static const M_mht:String = "message/rfc822rn"; public static const M_mhtml:String = "message/rfc822rn"; public static const M_mi:String = "application/x-mirn"; public static const M_mid:String = "audio/midrn"; public static const M_midi:String = "audio/midrn"; public static const M_mil:String = "application/x-milrn"; public static const M_mml:String = "text/xmlrn"; public static const M_mnd:String = "audio/x-musicnet-downloadrn"; public static const M_mns:String = "audio/x-musicnet-streamrn"; public static const M_mocha:String = "application/x-javascriptrn"; public static const M_movie:String = "video/x-sgi-moviern"; public static const M_mp1:String = "audio/mp1rn"; public static const M_mp2:String = "audio/mp2rn"; public static const M_mp2v:String = "video/mpegrn"; public static const M_mp3:String = "audio/mp3rn"; public static const M_mp4:String = "video/mpeg4rn"; public static const M_mpa:String = "video/x-mpgrn"; public static const M_mpd:String = "application/vnd.ms-projectrn"; public static const M_mpe:String = "video/x-mpegrn"; public static const M_mpeg:String = "video/mpgrn"; public static const M_mpg:String = "video/mpgrn"; public static const M_mpga:String = "audio/rn-mpegrn"; public static const M_mpp:String = "application/vnd.ms-projectrn"; public static const M_mps:String = "video/x-mpegrn"; public static const M_mpt:String = "application/vnd.ms-projectrn"; public static const M_mpv2:String = "video/mpegrn"; public static const M_mpv:String = "video/mpgrn"; public static const M_mpw:String = "application/vnd.ms-projectrn"; public static const M_mpx:String = "application/vnd.ms-projectrn"; public static const M_mtx:String = "text/xmlrn"; public static const M_mxp:String = "application/x-mmxprn"; public static const M_net:String = "image/pnetvuern"; public static const M_nrf:String = "application/x-nrfrn"; public static const M_nws:String = "message/rfc822rn"; public static const M_odc:String = "text/x-ms-odcrn"; public static const M_out:String = "application/x-outrn"; public static const M_p10:String = "application/pkcs10rn"; public static const M_p12:String = "application/x-pkcs12rn"; public static const M_p7b:String = "application/x-pkcs7-certificatesrn"; public static const M_p7c:String = "application/pkcs7-mimern"; public static const M_p7m:String = "application/pkcs7-mimern"; public static const M_p7r:String = "application/x-pkcs7-certreqresprn"; public static const M_p7s:String = "application/pkcs7-signaturern"; public static const M_pc5:String = "application/x-pc5rn"; public static const M_pci:String = "application/x-pcirn"; public static const M_pcl:String = "application/x-pclrn"; public static const M_pcx:String = "application/x-pcxrn"; public static const M_pdf:String = "application/pdfrn"; public static const M_pdx:String = "application/vnd.adobe.pdxrn"; public static const M_pfx:String = "application/x-pkcs12rn"; public static const M_pgl:String = "application/x-pglrn"; public static const M_pic:String = "application/x-picrn"; public static const M_pko:String = "application/vnd.ms-pki.pkorn"; public static const M_pl:String = "application/x-perlrn"; public static const M_plg:String = "text/htmlrn"; public static const M_pls:String = "audio/scplsrn"; public static const M_plt:String = "application/x-pltrn"; //public static const M_png:String = "application/x-pngrn"; public static const M_png:String = "image/pngrn"; public static const M_pot:String = "application/vnd.ms-powerpointrn"; public static const M_ppa:String = "application/vnd.ms-powerpointrn"; public static const M_ppm:String = "application/x-ppmrn"; public static const M_pps:String = "application/vnd.ms-powerpointrn"; //public static const M_ppt:String = "application/vnd.ms-powerpointrn"; public static const M_ppt:String = "application/x-pptrn"; public static const M_pr:String = "application/x-prrn"; public static const M_prf:String = "application/pics-rulesrn"; public static const M_prn:String = "application/x-prnrn"; public static const M_prt:String = "application/x-prtrn"; public static const M_ps:String = "application/x-psrn"; public static const M_ptn:String = "application/x-ptnrn"; public static const M_pwz:String = "application/vnd.ms-powerpointrn"; public static const M_r3t:String = "text/vnd.rn-realtext3drn"; public static const M_ra:String = "audio/vnd.rn-realaudiorn"; public static const M_ram:String = "audio/x-pn-realaudiorn"; public static const M_ras:String = "application/x-rasrn"; public static const M_rat:String = "application/rat-filern"; public static const M_rdf:String = "text/xmlrn"; public static const M_rec:String = "application/vnd.rn-recordingrn"; public static const M_red:String = "application/x-redrn"; public static const M_rgb:String = "application/x-rgbrn"; public static const M_rjs:String = "application/vnd.rn-realsystem-rjsrn"; public static const M_rjt:String = "application/vnd.rn-realsystem-rjtrn"; public static const M_rlc:String = "application/x-rlcrn"; public static const M_rle:String = "application/x-rlern"; public static const M_rm:String = "application/vnd.rn-realmediarn"; public static const M_rmf:String = "application/vnd.adobe.rmfrn"; public static const M_rmi:String = "audio/midrn"; public static const M_rmj:String = "application/vnd.rn-realsystem-rmjrn"; public static const M_rmm:String = "audio/x-pn-realaudiorn"; public static const M_rmp:String = "application/vnd.rn-rn_music_packagern"; public static const M_rms:String = "application/vnd.rn-realmedia-securern"; public static const M_rmvb:String = "application/vnd.rn-realmedia-vbrrn"; public static const M_rmx:String = "application/vnd.rn-realsystem-rmxrn"; public static const M_rnx:String = "application/vnd.rn-realplayerrn"; public static const M_rp:String = "image/vnd.rn-realpixrn"; public static const M_rpm:String = "audio/x-pn-realaudio-pluginrn"; public static const M_rsml:String = "application/vnd.rn-rsmlrn"; public static const M_rt:String = "text/vnd.rn-realtextrn"; //public static const M_rtf:String = "application/mswordrn"; public static const M_rtf:String = "application/x-rtfrn"; public static const M_rv:String = "video/vnd.rn-realvideorn"; public static const M_sam:String = "application/x-samrn"; public static const M_sat:String = "application/x-satrn"; public static const M_sdp:String = "application/sdprn"; public static const M_sdw:String = "application/x-sdwrn"; public static const M_sis:String = "application/vnd.symbian.installrn"; public static const M_sisx:String = "application/vnd.symbian.installrn"; public static const M_sit:String = "application/x-stuffitrn"; public static const M_slb:String = "application/x-slbrn"; public static const M_sld:String = "application/x-sldrn"; public static const M_slk:String = "drawing/x-slkrn"; public static const M_smi:String = "application/smilrn"; public static const M_smil:String = "application/smilrn"; public static const M_smk:String = "application/x-smkrn"; public static const M_snd:String = "audio/basicrn"; public static const M_sol:String = "text/plainrn"; public static const M_sor:String = "text/plainrn"; public static const M_spc:String = "application/x-pkcs7-certificatesrn"; public static const M_spl:String = "application/futuresplashrn"; public static const M_spp:String = "text/xmlrn"; public static const M_ssm:String = "application/streamingmediarn"; public static const M_sst:String = "application/vnd.ms-pki.certstorern"; public static const M_stl:String = "application/vnd.ms-pki.stlrn"; public static const M_stm:String = "text/htmlrn"; public static const M_sty:String = "application/x-styrn"; public static const M_svg:String = "text/xmlrn"; public static const M_swf:String = "application/x-shockwave-flashrn"; public static const M_tdf:String = "application/x-tdfrn"; public static const M_tg4:String = "application/x-tg4rn"; public static const M_tga:String = "application/x-tgarn"; //public static const M_tif:String = "application/x-tifrn"; public static const M_tif:String = "image/tiffrn"; public static const M_tiff:String = "image/tiffrn"; public static const M_tld:String = "text/xmlrn"; public static const M_top:String = "drawing/x-toprn"; public static const M_torrent:String = "application/x-bittorrentrn"; public static const M_tsd:String = "text/xmlrn"; public static const M_txt:String = "text/plainrn"; public static const M_uin:String = "application/x-icqrn"; public static const M_uls:String = "text/iulsrn"; public static const M_vcf:String = "text/x-vcardrn"; public static const M_vda:String = "application/x-vdarn"; public static const M_vdx:String = "application/vnd.visiorn"; public static const M_vml:String = "text/xmlrn"; public static const M_vpg:String = "application/x-vpeg005rn"; public static const M_vsd:String = "application/vnd.visiorn"; //public static const M_vsd:String = "application/x-vsdrn"; public static const M_vss:String = "application/vnd.visiorn"; //public static const M_vst:String = "application/vnd.visiorn"; public static const M_vst:String = "application/x-vstrn"; public static const M_vsw:String = "application/vnd.visiorn"; public static const M_vsx:String = "application/vnd.visiorn"; public static const M_vtx:String = "application/vnd.visiorn"; public static const M_vxml:String = "text/xmlrn"; public static const M_wav:String = "audio/wavrn"; public static const M_wax:String = "audio/x-ms-waxrn"; public static const M_wb1:String = "application/x-wb1rn"; public static const M_wb2:String = "application/x-wb2rn"; public static const M_wb3:String = "application/x-wb3rn"; public static const M_wbmp:String = "image/vnd.wap.wbmprn"; public static const M_wiz:String = "application/mswordrn"; public static const M_wk3:String = "application/x-wk3rn"; public static const M_wk4:String = "application/x-wk4rn"; public static const M_wkq:String = "application/x-wkqrn"; public static const M_wks:String = "application/x-wksrn"; public static const M_wm:String = "video/x-ms-wmrn"; public static const M_wma:String = "audio/x-ms-wmarn"; public static const M_wmd:String = "application/x-ms-wmdrn"; public static const M_wmf:String = "application/x-wmfrn"; public static const M_wml:String = "text/vnd.wap.wmlrn"; public static const M_wmv:String = "video/x-ms-wmvrn"; public static const M_wmx:String = "video/x-ms-wmxrn"; public static const M_wmz:String = "application/x-ms-wmzrn"; public static const M_wp6:String = "application/x-wp6rn"; public static const M_wpd:String = "application/x-wpdrn"; public static const M_wpg:String = "application/x-wpgrn"; public static const M_wpl:String = "application/vnd.ms-wplrn"; public static const M_wq1:String = "application/x-wq1rn"; public static const M_wr1:String = "application/x-wr1rn"; public static const M_wri:String = "application/x-wrirn"; public static const M_wrk:String = "application/x-wrkrn"; public static const M_ws2:String = "application/x-wsrn"; public static const M_ws:String = "application/x-wsrn"; public static const M_wsc:String = "text/scriptletrn"; public static const M_wsdl:String = "text/xmlrn"; public static const M_wvx:String = "video/x-ms-wvxrn"; public static const M_x_b:String = "application/x-x_brn"; public static const M_x_t:String = "application/x-x_trn"; public static const M_xap:String = "application/x-silverlight-apprn"; public static const M_xdp:String = "application/vnd.adobe.xdprn"; public static const M_xdr:String = "text/xmlrn"; public static const M_xfd:String = "application/vnd.adobe.xfdrn"; public static const M_xfdf:String = "application/vnd.adobe.xfdfrn"; public static const M_xhtml:String = "text/htmlrn"; //public static const M_xls:String = "application/vnd.ms-excelrn"; public static const M_xls:String = "application/x-xlsrn"; public static const M_xlw:String = "application/x-xlwrn"; public static const M_xml:String = "text/xmlrn"; public static const M_xpl:String = "audio/scplsrn"; public static const M_xq:String = "text/xmlrn"; public static const M_xql:String = "text/xmlrn"; public static const M_xquery:String = "text/xmlrn"; public static const M_xsd:String = "text/xmlrn"; public static const M_xsl:String = "text/xmlrn"; public static const M_xslt:String = "text/xmlrn"; public static const M_xwd:String = "application/x-xwdrn"; public static const M_zip:String = "application/x-zip-compressedrn"; public function Mime() { } } } 视频链接======================================================================所有 get-mv-info 前缀为: http://www.yinyuetai.com/main/ AKB48 - 真夏のSounds good ! AOA专访 - 王牌天使 怦然心动!? 少女时代 - Party - MBC 音乐中心 现场版? 爱してる-- 高铃: 其它链接: AKB48 - Bガーデン ? ? ? v.yinyuetai.com/video/2054540 这里是VIP展览,感受一下AOA的1080的超高清: 参考资料====================================================================== Network Sniffer and Connection Analyzer http://www.codeproject.com/Articles/8254/Network-Sniffer-and-Connection-Analyzer SharpPcap A Packet Capture Framework for NET http://www.codeproject.com/Articles/12458/SharpPcap-A-Packet-Capture-Framework-for-NET Getting the active TCP/UDP connections using the GetExtendedTcpTable function http://www.codeproject.com/Articles/14423/Getting-the-active-TCP-UDP-connections-using-the-G Getting active TCP/UDP connections on a box http://www.codeproject.com/Articles/4298/Getting-active-TCP-UDP-connections-on-a-box 《【原创】Sysinternal出品工具TcpView的驱动逆向源代码》 vxasm http://bbs.pediy.com/showthread.php?t=69543 Hessian Flash-only (不需要Flex框架支持): http://hessian.caucho.com/download/hessian-flash-3_1-snap.swc http://hessian.caucho.com/download/hessian-flex-3_1-snap-src.jar 其它相关工具下载 http://www.bizon.org/ilya/sniffer80.htm https://github.com/PcapDotNet/Pcap.Net http://sourceforge.net/projects/sharppcap/ http://hessian.caucho.com/#FlashFlex(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |