引言
上一篇 《Socket与站点保密应用 (隐藏链接的视频下载)》大大咧咧地从 WEB 讲 Socket。再到 TCP/IP
等协议,又再讲到 Wireshark 怎样抓IP包分析。最还要复习一下路由与网络的知识。真的涉及面太广了,仅仅能蜻蜓点水一一带过,只是将多领域的知识串烧也是不错的,能够起到一个归纳的作用。这篇针对 Flash 来进行。写作思路以解决这个问题的过程行为线索。
依次展示怎样使用 Flex Air 的 ServerSocket 和 Socket 实现简化版本号的 HTTP server,以及怎样载入外部的 SWF 文件并进行操作。
在 mplayer.swf 内部,使用 FlasCC 集成 C 代码做保护。使用了 Hessian 做对象序列化。Hessian是一个由Caucho Technology开发的轻量级二进制RPC协议。Hessian 自称为 binary web service protocol
。看来加了个 protocol 的都不简单了,好几个平台的版本号都出来了。FlasCC 的加密部分似乎和 cmodule.usemd5 包下的 FSM_encode 这个类有关,这里截一片代码出来。看有没人了解一二:
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福利滋润一下各位看官:)。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
//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 server的数据,由于改变了 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 请求数据时。去本地的server取数据了,本地server最多就是产生一条 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.
=========================================================================
看上的server已经变成 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],[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 server。
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
======================================================================
微缩HTTPserver实现
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", HOST).replace("VB", 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, 0, len); var txt:String = buf.readUTFBytes(len);
while( txt.length<len){ // skip \0 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.remoteAddress).replace("VB", 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); // \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 OK\r\n";
public static const HTTP201:String = "HTTP/1.1 201 Created\r\n";
public static const HTTP202:String = "HTTP/1.1 202 Accepted\r\n";
public static const HTTP203:String = "HTTP/1.1 203 Non-Authoritative Information\r\n";
public static const HTTP204:String = "HTTP/1.1 204 No Content\r\n";
public static const HTTP205:String = "HTTP/1.1 205 Reset Content\r\n";
public static const HTTP206:String = "HTTP/1.1 206 Partial Content\r\n"; public static const HTTP300:String = "HTTP/1.1 300 Multiple Choices\r\n";
public static const HTTP301:String = "HTTP/1.1 301 Moved Permanently\r\n";
public static const HTTP302:String = "HTTP/1.1 302 Found\r\n";
public static const HTTP303:String = "HTTP/1.1 303 See Other\r\n";
public static const HTTP304:String = "HTTP/1.1 304 Not Modified\r\n";
public static const HTTP305:String = "HTTP/1.1 305 Use Proxy\r\n";
public static const HTTP306:String = "HTTP/1.1 306 (Unused)\r\n";
public static const HTTP307:String = "HTTP/1.1 307 Temporary Redirect\r\n"; public static const HTTP400:String = "HTTP/1.1 400 Bad Request\r\n";
public static const HTTP401:String = "HTTP/1.1 401 Unauthorized\r\n";
public static const HTTP402:String = "HTTP/1.1 402 Payment Required\r\n";
public static const HTTP403:String = "HTTP/1.1 403 Forbidden\r\n";
public static const HTTP404:String = "HTTP/1.1 404 Not Found\r\n";
public static const HTTP405:String = "HTTP/1.1 405 Method Not Allowed\r\n";
public static const HTTP406:String = "HTTP/1.1 406 Not Acceptable\r\n";
public static const HTTP407:String = "HTTP/1.1 407 Proxy Authentication Required\r\n";
public static const HTTP408:String = "HTTP/1.1 408 Request Timeout\r\n";
public static const HTTP409:String = "HTTP/1.1 409 Conflict\r\n";
public static const HTTP410:String = "HTTP/1.1 410 Gone\r\n";
public static const HTTP411:String = "HTTP/1.1 411 Length Required\r\n";
public static const HTTP412:String = "HTTP/1.1 412 Precondition Failed\r\n";
public static const HTTP413:String = "HTTP/1.1 413 Request Entity Too Large\r\n";
public static const HTTP414:String = "HTTP/1.1 414 Request-URI Too Long\r\n";
public static const HTTP415:String = "HTTP/1.1 415 Unsupported Media Type\r\n";
public static const HTTP416:String = "HTTP/1.1 416 Requested Range Not Satisfiable\r\n";
public static const HTTP417:String = "HTTP/1.1 417 Expectation Failed\r\n"; public static const HTTP500:String = "HTTP/1.1 500 Internal Server Error\r\n";
public static const HTTP501:String = "HTTP/1.1 501 Not Implemented\r\n";
public static const HTTP502:String = "HTTP/1.1 502 Bad Gateway\r\n";
public static const HTTP503:String = "HTTP/1.1 503 Service Unavailable\r\n";
public static const HTTP504:String = "HTTP/1.1 504 Gateway Timeout\r\n";
public static const HTTP505:String = "HTTP/1.1 505 HTTP Version Not Supported\r\n"; public static const HTTP520:String = "HTTP/1.1 520 Error setHttpStatus VA\r\n"; public static const ContentLength:String = "Content-Length: VA\r\n"; public static const HEADSPLITER:String = "\r\n";
public static const RGET:RegExp = /^(GET) (.+) (HTTP\/1.1)$/; public static const SERVER:String = "Server: ServerSocket by Jimbowhy\r\n"; public static function setHeader(sok:Socket, name:String, value:String):void
{
sok.writeUTFBytes(name + ": " + value + "\r\n");
}
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-001\r\n";
public static const M_301:String = "application/x-301\r\n";
public static const M_323:String = "text/h323\r\n";
public static const M_906:String = "application/x-906\r\n";
public static const M_907:String = "drawing/907\r\n";
public static const M_BIN:String = "application/octet-stream\r\n";
public static const M_IVF:String = "video/x-ivf\r\n";
public static const M_a11:String = "application/x-a11\r\n";
public static const M_acp:String = "audio/x-mei-aac\r\n";
public static const M_ai:String = "application/postscript\r\n";
public static const M_aif:String = "audio/aiff\r\n";
public static const M_aifc:String = "audio/aiff\r\n";
public static const M_aiff:String = "audio/aiff\r\n";
public static const M_anv:String = "application/x-anv\r\n";
public static const M_apk:String = "application/vnd.android.package-archive\r\n";
public static const M_asa:String = "text/asa\r\n";
public static const M_asf:String = "video/x-ms-asf\r\n";
public static const M_asp:String = "text/asp\r\n";
public static const M_asx:String = "video/x-ms-asf\r\n";
public static const M_au:String = "audio/basic\r\n";
public static const M_avi:String = "video/avi\r\n";
public static const M_awf:String = "application/vnd.adobe.workflow\r\n";
public static const M_biz:String = "text/xml\r\n";
public static const M_bmp:String = "application/x-bmp\r\n";
public static const M_bot:String = "application/x-bot\r\n";
public static const M_c4t:String = "application/x-c4t\r\n";
public static const M_c90:String = "application/x-c90\r\n";
public static const M_cal:String = "application/x-cals\r\n";
public static const M_cat:String = "application/vnd.ms-pki.seccat\r\n";
public static const M_cdf:String = "application/x-netcdf\r\n";
public static const M_cdr:String = "application/x-cdr\r\n";
public static const M_cel:String = "application/x-cel\r\n";
public static const M_cer:String = "application/x-x509-ca-cert\r\n";
public static const M_cg4:String = "application/x-g4\r\n";
public static const M_cgm:String = "application/x-cgm\r\n";
public static const M_cit:String = "application/x-cit\r\n";
public static const M_class:String = "java/*\r\n";
public static const M_cml:String = "text/xml\r\n";
public static const M_cmp:String = "application/x-cmp\r\n";
public static const M_cmx:String = "application/x-cmx\r\n";
public static const M_cot:String = "application/x-cot\r\n";
public static const M_crl:String = "application/pkix-crl\r\n";
public static const M_crt:String = "application/x-x509-ca-cert\r\n";
public static const M_csi:String = "application/x-csi\r\n";
public static const M_css:String = "text/css\r\n";
public static const M_cut:String = "application/x-cut\r\n";
public static const M_dbf:String = "application/x-dbf\r\n";
public static const M_dbm:String = "application/x-dbm\r\n";
public static const M_dbx:String = "application/x-dbx\r\n";
public static const M_dcd:String = "text/xml\r\n";
public static const M_dcx:String = "application/x-dcx\r\n";
public static const M_der:String = "application/x-x509-ca-cert\r\n";
public static const M_dgn:String = "application/x-dgn\r\n";
public static const M_dib:String = "application/x-dib\r\n";
public static const M_dll:String = "application/x-msdownload\r\n";
public static const M_doc:String = "application/msword\r\n";
public static const M_dot:String = "application/msword\r\n";
public static const M_drw:String = "application/x-drw\r\n";
public static const M_dtd:String = "text/xml\r\n";
//public static const M_dwf:String = "Model/vnd.dwf\r\n";
public static const M_dwf:String = "application/x-dwf\r\n";
public static const M_dwg:String = "application/x-dwg\r\n";
public static const M_dxb:String = "application/x-dxb\r\n";
public static const M_dxf:String = "application/x-dxf\r\n";
public static const M_edn:String = "application/vnd.adobe.edn\r\n";
public static const M_emf:String = "application/x-emf\r\n";
public static const M_eml:String = "message/rfc822\r\n";
public static const M_ent:String = "text/xml\r\n";
public static const M_epi:String = "application/x-epi\r\n";
public static const M_eps:String = "application/postscript\r\n";
public static const M_etd:String = "application/x-ebx\r\n";
public static const M_exe:String = "application/x-msdownload\r\n";
public static const M_fax:String = "image/fax\r\n";
public static const M_fdf:String = "application/vnd.fdf\r\n";
public static const M_fif:String = "application/fractals\r\n";
public static const M_fo:String = "text/xml\r\n";
public static const M_frm:String = "application/x-frm\r\n";
public static const M_g4:String = "application/x-g4\r\n";
public static const M_gbr:String = "application/x-gbr\r\n";
public static const M_gif:String = "image/gif\r\n";
public static const M_gl2:String = "application/x-gl2\r\n";
public static const M_gp4:String = "application/x-gp4\r\n";
public static const M_hgl:String = "application/x-hgl\r\n";
public static const M_hmr:String = "application/x-hmr\r\n";
public static const M_hpg:String = "application/x-hpgl\r\n";
public static const M_hpl:String = "application/x-hpl\r\n";
public static const M_hqx:String = "application/mac-binhex40\r\n";
public static const M_hrf:String = "application/x-hrf\r\n";
public static const M_hta:String = "application/hta\r\n";
public static const M_htc:String = "text/x-component\r\n";
public static const M_htm:String = "text/html\r\n";
public static const M_html:String = "text/html\r\n";
public static const M_htt:String = "text/webviewhtml\r\n";
public static const M_htx:String = "text/html\r\n";
public static const M_icb:String = "application/x-icb\r\n";
public static const M_ico:String = "application/x-ico\r\n";
//public static const M_ico:String = "image/x-icon\r\n";
public static const M_iff:String = "application/x-iff\r\n";
public static const M_ig4:String = "application/x-g4\r\n";
public static const M_igs:String = "application/x-igs\r\n";
public static const M_iii:String = "application/x-iphone\r\n";
public static const M_img:String = "application/x-img\r\n";
public static const M_ins:String = "application/x-internet-signup\r\n";
public static const M_ipa:String = "application/vnd.iphone\r\n";
public static const M_isp:String = "application/x-internet-signup\r\n";
public static const M_java:String = "java/*\r\n";
public static const M_jfif:String = "image/jpeg\r\n";
//public static const M_jpe:String = "application/x-jpe\r\n";
public static const M_jpe:String = "image/jpeg\r\n";
public static const M_jpeg:String = "image/jpeg\r\n";
//public static const M_jpg:String = "application/x-jpg\r\n";
public static const M_jpg:String = "image/jpeg\r\n";
public static const M_js:String = "application/x-javascript\r\n";
public static const M_jsp:String = "text/html\r\n";
public static const M_la1:String = "audio/x-liquid-file\r\n";
public static const M_lar:String = "application/x-laplayer-reg\r\n";
public static const M_latex:String = "application/x-latex\r\n";
public static const M_lavs:String = "audio/x-liquid-secure\r\n";
public static const M_lbm:String = "application/x-lbm\r\n";
public static const M_lmsff:String = "audio/x-la-lms\r\n";
public static const M_ls:String = "application/x-javascript\r\n";
public static const M_ltr:String = "application/x-ltr\r\n";
public static const M_m1v:String = "video/x-mpeg\r\n";
public static const M_m2v:String = "video/x-mpeg\r\n";
public static const M_m3u:String = "audio/mpegurl\r\n";
public static const M_m4e:String = "video/mpeg4\r\n";
public static const M_mac:String = "application/x-mac\r\n";
public static const M_man:String = "application/x-troff-man\r\n";
public static const M_math:String = "text/xml\r\n";
//public static const M_mdb:String = "application/msaccess\r\n";
public static const M_mdb:String = "application/x-mdb\r\n";
public static const M_mfp:String = "application/x-shockwave-flash\r\n";
public static const M_mht:String = "message/rfc822\r\n";
public static const M_mhtml:String = "message/rfc822\r\n";
public static const M_mi:String = "application/x-mi\r\n";
public static const M_mid:String = "audio/mid\r\n";
public static const M_midi:String = "audio/mid\r\n";
public static const M_mil:String = "application/x-mil\r\n";
public static const M_mml:String = "text/xml\r\n";
public static const M_mnd:String = "audio/x-musicnet-download\r\n";
public static const M_mns:String = "audio/x-musicnet-stream\r\n";
public static const M_mocha:String = "application/x-javascript\r\n";
public static const M_movie:String = "video/x-sgi-movie\r\n";
public static const M_mp1:String = "audio/mp1\r\n";
public static const M_mp2:String = "audio/mp2\r\n";
public static const M_mp2v:String = "video/mpeg\r\n";
public static const M_mp3:String = "audio/mp3\r\n";
public static const M_mp4:String = "video/mpeg4\r\n";
public static const M_mpa:String = "video/x-mpg\r\n";
public static const M_mpd:String = "application/vnd.ms-project\r\n";
public static const M_mpe:String = "video/x-mpeg\r\n";
public static const M_mpeg:String = "video/mpg\r\n";
public static const M_mpg:String = "video/mpg\r\n";
public static const M_mpga:String = "audio/rn-mpeg\r\n";
public static const M_mpp:String = "application/vnd.ms-project\r\n";
public static const M_mps:String = "video/x-mpeg\r\n";
public static const M_mpt:String = "application/vnd.ms-project\r\n";
public static const M_mpv2:String = "video/mpeg\r\n";
public static const M_mpv:String = "video/mpg\r\n";
public static const M_mpw:String = "application/vnd.ms-project\r\n";
public static const M_mpx:String = "application/vnd.ms-project\r\n";
public static const M_mtx:String = "text/xml\r\n";
public static const M_mxp:String = "application/x-mmxp\r\n";
public static const M_net:String = "image/pnetvue\r\n";
public static const M_nrf:String = "application/x-nrf\r\n";
public static const M_nws:String = "message/rfc822\r\n";
public static const M_odc:String = "text/x-ms-odc\r\n";
public static const M_out:String = "application/x-out\r\n";
public static const M_p10:String = "application/pkcs10\r\n";
public static const M_p12:String = "application/x-pkcs12\r\n";
public static const M_p7b:String = "application/x-pkcs7-certificates\r\n";
public static const M_p7c:String = "application/pkcs7-mime\r\n";
public static const M_p7m:String = "application/pkcs7-mime\r\n";
public static const M_p7r:String = "application/x-pkcs7-certreqresp\r\n";
public static const M_p7s:String = "application/pkcs7-signature\r\n";
public static const M_pc5:String = "application/x-pc5\r\n";
public static const M_pci:String = "application/x-pci\r\n";
public static const M_pcl:String = "application/x-pcl\r\n";
public static const M_pcx:String = "application/x-pcx\r\n";
public static const M_pdf:String = "application/pdf\r\n";
public static const M_pdx:String = "application/vnd.adobe.pdx\r\n";
public static const M_pfx:String = "application/x-pkcs12\r\n";
public static const M_pgl:String = "application/x-pgl\r\n";
public static const M_pic:String = "application/x-pic\r\n";
public static const M_pko:String = "application/vnd.ms-pki.pko\r\n";
public static const M_pl:String = "application/x-perl\r\n";
public static const M_plg:String = "text/html\r\n";
public static const M_pls:String = "audio/scpls\r\n";
public static const M_plt:String = "application/x-plt\r\n";
//public static const M_png:String = "application/x-png\r\n";
public static const M_png:String = "image/png\r\n";
public static const M_pot:String = "application/vnd.ms-powerpoint\r\n";
public static const M_ppa:String = "application/vnd.ms-powerpoint\r\n";
public static const M_ppm:String = "application/x-ppm\r\n";
public static const M_pps:String = "application/vnd.ms-powerpoint\r\n";
//public static const M_ppt:String = "application/vnd.ms-powerpoint\r\n";
public static const M_ppt:String = "application/x-ppt\r\n";
public static const M_pr:String = "application/x-pr\r\n";
public static const M_prf:String = "application/pics-rules\r\n";
public static const M_prn:String = "application/x-prn\r\n";
public static const M_prt:String = "application/x-prt\r\n";
public static const M_ps:String = "application/x-ps\r\n";
public static const M_ptn:String = "application/x-ptn\r\n";
public static const M_pwz:String = "application/vnd.ms-powerpoint\r\n";
public static const M_r3t:String = "text/vnd.rn-realtext3d\r\n";
public static const M_ra:String = "audio/vnd.rn-realaudio\r\n";
public static const M_ram:String = "audio/x-pn-realaudio\r\n";
public static const M_ras:String = "application/x-ras\r\n";
public static const M_rat:String = "application/rat-file\r\n";
public static const M_rdf:String = "text/xml\r\n";
public static const M_rec:String = "application/vnd.rn-recording\r\n";
public static const M_red:String = "application/x-red\r\n";
public static const M_rgb:String = "application/x-rgb\r\n";
public static const M_rjs:String = "application/vnd.rn-realsystem-rjs\r\n";
public static const M_rjt:String = "application/vnd.rn-realsystem-rjt\r\n";
public static const M_rlc:String = "application/x-rlc\r\n";
public static const M_rle:String = "application/x-rle\r\n";
public static const M_rm:String = "application/vnd.rn-realmedia\r\n";
public static const M_rmf:String = "application/vnd.adobe.rmf\r\n";
public static const M_rmi:String = "audio/mid\r\n";
public static const M_rmj:String = "application/vnd.rn-realsystem-rmj\r\n";
public static const M_rmm:String = "audio/x-pn-realaudio\r\n";
public static const M_rmp:String = "application/vnd.rn-rn_music_package\r\n";
public static const M_rms:String = "application/vnd.rn-realmedia-secure\r\n";
public static const M_rmvb:String = "application/vnd.rn-realmedia-vbr\r\n";
public static const M_rmx:String = "application/vnd.rn-realsystem-rmx\r\n";
public static const M_rnx:String = "application/vnd.rn-realplayer\r\n";
public static const M_rp:String = "image/vnd.rn-realpix\r\n";
public static const M_rpm:String = "audio/x-pn-realaudio-plugin\r\n";
public static const M_rsml:String = "application/vnd.rn-rsml\r\n";
public static const M_rt:String = "text/vnd.rn-realtext\r\n";
//public static const M_rtf:String = "application/msword\r\n";
public static const M_rtf:String = "application/x-rtf\r\n";
public static const M_rv:String = "video/vnd.rn-realvideo\r\n";
public static const M_sam:String = "application/x-sam\r\n";
public static const M_sat:String = "application/x-sat\r\n";
public static const M_sdp:String = "application/sdp\r\n";
public static const M_sdw:String = "application/x-sdw\r\n";
public static const M_sis:String = "application/vnd.symbian.install\r\n";
public static const M_sisx:String = "application/vnd.symbian.install\r\n";
public static const M_sit:String = "application/x-stuffit\r\n";
public static const M_slb:String = "application/x-slb\r\n";
public static const M_sld:String = "application/x-sld\r\n";
public static const M_slk:String = "drawing/x-slk\r\n";
public static const M_smi:String = "application/smil\r\n";
public static const M_smil:String = "application/smil\r\n";
public static const M_smk:String = "application/x-smk\r\n";
public static const M_snd:String = "audio/basic\r\n";
public static const M_sol:String = "text/plain\r\n";
public static const M_sor:String = "text/plain\r\n";
public static const M_spc:String = "application/x-pkcs7-certificates\r\n";
public static const M_spl:String = "application/futuresplash\r\n";
public static const M_spp:String = "text/xml\r\n";
public static const M_ssm:String = "application/streamingmedia\r\n";
public static const M_sst:String = "application/vnd.ms-pki.certstore\r\n";
public static const M_stl:String = "application/vnd.ms-pki.stl\r\n";
public static const M_stm:String = "text/html\r\n";
public static const M_sty:String = "application/x-sty\r\n";
public static const M_svg:String = "text/xml\r\n";
public static const M_swf:String = "application/x-shockwave-flash\r\n";
public static const M_tdf:String = "application/x-tdf\r\n";
public static const M_tg4:String = "application/x-tg4\r\n";
public static const M_tga:String = "application/x-tga\r\n";
//public static const M_tif:String = "application/x-tif\r\n";
public static const M_tif:String = "image/tiff\r\n";
public static const M_tiff:String = "image/tiff\r\n";
public static const M_tld:String = "text/xml\r\n";
public static const M_top:String = "drawing/x-top\r\n";
public static const M_torrent:String = "application/x-bittorrent\r\n";
public static const M_tsd:String = "text/xml\r\n";
public static const M_txt:String = "text/plain\r\n";
public static const M_uin:String = "application/x-icq\r\n";
public static const M_uls:String = "text/iuls\r\n";
public static const M_vcf:String = "text/x-vcard\r\n";
public static const M_vda:String = "application/x-vda\r\n";
public static const M_vdx:String = "application/vnd.visio\r\n";
public static const M_vml:String = "text/xml\r\n";
public static const M_vpg:String = "application/x-vpeg005\r\n";
public static const M_vsd:String = "application/vnd.visio\r\n";
//public static const M_vsd:String = "application/x-vsd\r\n";
public static const M_vss:String = "application/vnd.visio\r\n";
//public static const M_vst:String = "application/vnd.visio\r\n";
public static const M_vst:String = "application/x-vst\r\n";
public static const M_vsw:String = "application/vnd.visio\r\n";
public static const M_vsx:String = "application/vnd.visio\r\n";
public static const M_vtx:String = "application/vnd.visio\r\n";
public static const M_vxml:String = "text/xml\r\n";
public static const M_wav:String = "audio/wav\r\n";
public static const M_wax:String = "audio/x-ms-wax\r\n";
public static const M_wb1:String = "application/x-wb1\r\n";
public static const M_wb2:String = "application/x-wb2\r\n";
public static const M_wb3:String = "application/x-wb3\r\n";
public static const M_wbmp:String = "image/vnd.wap.wbmp\r\n";
public static const M_wiz:String = "application/msword\r\n";
public static const M_wk3:String = "application/x-wk3\r\n";
public static const M_wk4:String = "application/x-wk4\r\n";
public static const M_wkq:String = "application/x-wkq\r\n";
public static const M_wks:String = "application/x-wks\r\n";
public static const M_wm:String = "video/x-ms-wm\r\n";
public static const M_wma:String = "audio/x-ms-wma\r\n";
public static const M_wmd:String = "application/x-ms-wmd\r\n";
public static const M_wmf:String = "application/x-wmf\r\n";
public static const M_wml:String = "text/vnd.wap.wml\r\n";
public static const M_wmv:String = "video/x-ms-wmv\r\n";
public static const M_wmx:String = "video/x-ms-wmx\r\n";
public static const M_wmz:String = "application/x-ms-wmz\r\n";
public static const M_wp6:String = "application/x-wp6\r\n";
public static const M_wpd:String = "application/x-wpd\r\n";
public static const M_wpg:String = "application/x-wpg\r\n";
public static const M_wpl:String = "application/vnd.ms-wpl\r\n";
public static const M_wq1:String = "application/x-wq1\r\n";
public static const M_wr1:String = "application/x-wr1\r\n";
public static const M_wri:String = "application/x-wri\r\n";
public static const M_wrk:String = "application/x-wrk\r\n";
public static const M_ws2:String = "application/x-ws\r\n";
public static const M_ws:String = "application/x-ws\r\n";
public static const M_wsc:String = "text/scriptlet\r\n";
public static const M_wsdl:String = "text/xml\r\n";
public static const M_wvx:String = "video/x-ms-wvx\r\n";
public static const M_x_b:String = "application/x-x_b\r\n";
public static const M_x_t:String = "application/x-x_t\r\n";
public static const M_xap:String = "application/x-silverlight-app\r\n";
public static const M_xdp:String = "application/vnd.adobe.xdp\r\n";
public static const M_xdr:String = "text/xml\r\n";
public static const M_xfd:String = "application/vnd.adobe.xfd\r\n";
public static const M_xfdf:String = "application/vnd.adobe.xfdf\r\n";
public static const M_xhtml:String = "text/html\r\n";
//public static const M_xls:String = "application/vnd.ms-excel\r\n";
public static const M_xls:String = "application/x-xls\r\n";
public static const M_xlw:String = "application/x-xlw\r\n";
public static const M_xml:String = "text/xml\r\n";
public static const M_xpl:String = "audio/scpls\r\n";
public static const M_xq:String = "text/xml\r\n";
public static const M_xql:String = "text/xml\r\n";
public static const M_xquery:String = "text/xml\r\n";
public static const M_xsd:String = "text/xml\r\n";
public static const M_xsl:String = "text/xml\r\n";
public static const M_xslt:String = "text/xml\r\n";
public static const M_xwd:String = "application/x-xwd\r\n";
public static const M_zip:String = "application/x-zip-compressed\r\n"; public function Mime()
{ } } }
视频链接
======================================================================
全部 get-mv-info 前缀为: http://www.yinyuetai.com/main/
AKB48 - 真夏のSounds good !
get-mv-info?flex=true&sc=bacd04f73c560b6432c43e5e3c5c3eb9&t=4797407&v=1.8.2.2&videoId=398619
流畅 40MB http://hc.yinyuetai.com/uploads/videos/common/F466013AB6C9120E52E98349C292DE47.flv
高清 56MB http://hd.yinyuetai.com/uploads/videos/common/2C65013AD50F006FD35FE181C9551007.flv
AOA专訪 - 王牌天使 怦然心动!
get-mv-info?flex=true&sc=ee4fb9b09346bd933dd22e37fe978741&t=4797398&v=1.8.2.2&videoId=2344403
LT 50MB http://hc.yinyuetai.com/uploads/videos/common/3132014EF85A8CE3ADF791CC5E279802.flv
SD 71MB http://hd.yinyuetai.com/uploads/videos/common/757B014EF85F24E2341DCCA341D31C53.flv
HD 203MB http://he.yinyuetai.com/uploads/videos/common/1816014EF85F24DBDDA5B109E2710BA3.flv
VIP 398MB http://sh.yinyuetai.com/uploads/videos/common/EF43014EF85F24D5360F07B4721B30D6.mp4
AOA - 胸キュン 完整版
get-mv-info?flex=true&sc=02cdd2a81d89ce0fea835e1dd678bfdb&t=4797686&v=1.8.2.2&videoId=2340250
LT http://hc.yinyuetai.com/uploads/videos/common/31E2014EDD026BFBF62BA8B5D17C5A76.flv
HD http://hd.yinyuetai.com/uploads/videos/common/63EB014EDD6964447B14EE32E183CEEF.fl
FHD http://he.yinyuetai.com/uploads/videos/common/DD24014EDD69643E5090A131A6E2037B.flv
VIP http://sh.yinyuetai.com/uploads/videos/common/E761014EDD6964382D7A2B5F9C5FBEC9.mp4
少女时代 - Party - MBC 音乐中心 现场版
get-mv-info?flex=true&sc=0295650498d599e87d08606efdc81e3a&t=4797689&v=1.8.2.2&videoId=2342124
http://hc.yinyuetai.com/uploads/videos/common/15B2014EEC958C659D81B6494BEF2229.flv
http://hd.yinyuetai.com/uploads/videos/common/BCF3014EECD1ADE87ACA388D99255D62.flv
http://he.yinyuetai.com/uploads/videos/common/D6CC014EECD1ADE1352C8903233358E6.flv
http://sh.yinyuetai.com/uploads/videos/common/7A7F014EECD1ADDA3FE62CEC444FE149.mp4
爱してる-- 高铃:
LT 26MB http://hc.yinyuetai.com/32A00127BA9B8DBB4FA3B950FEC648DF.flv
其他链接:
get-mv-info?flex=true&sc=f16935827aa59a8c6da702c0d0942c1b&t=4797690&v=1.8.2.2&videoId=121753
Visual Dreams-- 少女时代
get-mv-info?flex=true&sc=4ec07f9e6d21d1ee77c4b60fe4369ca0&t=4797691&v=1.8.2.2&videoId=2291949
君の第二章-- AKB48
AKB48 - Bガーデン v.yinyuetai.com/video/2054540
AKB48 - Green Flash v.yinyuetai.com/video/2242261
AKB48 - 掌が語ること v.yinyuetai.com/video/635854
AKB48 - 心のプラカード v.yinyuetai.com/video/2107919
AKB48 - 希望的リフレインv.yinyuetai.com/video/2173512
AKB48 SHOW! Ep49 らしくない v.yinyuetai.com/video/2180838
AKB48 - 真夏のSounds good! v.yinyuetai.com/video/398619
NMB48 - らしくない v.yinyuetai.com/video/2157631
NMB48 - ドリアン少年 v.yinyuetai.com/video/2315990
NMB48 - イビサガール v.yinyuetai.com/video/2086511
AKB48 - 旅立ちのとき v.yinyuetai.com/video/545647
AKB48 - 恋するフォーチュンクッキー v.yinyuetai.com/video/731559
AKB48 - 今日までのメロディー v.yinyuetai.com/video/2054363
AKB48 - ラブラドール.レトリバー v.yinyuetai.com/video/2043120
AKB48 - チューインガムの味がなくなるまで v.yinyuetai.com/video/2120433
Video info: AKB48 - 希望的リフレイン 完整版
流畅 30.96MB http://hc.yinyuetai.com/uploads/videos/common/E718014978E084B90CE9F71076C68CB9.flv?
sc=b30f638dfad44b5f&br=781&vid=2173512&aid=994&area=JP&vst=0
高清 43.71MB http://hd.yinyuetai.com/uploads/videos/common/153F014978F9C6BFBE66E465A6EFACD0.flv?
sc=8142315d78cfaf6c&br=1103&vid=2173512&aid=994&area=JP&vst=0
超清 124.29MB http://he.yinyuetai.com/uploads/videos/common/B25D014978F9C6C59D7F1DB4CBD81D78.flv?sc=b46f38dffaa8fb5b&br=3138&vid=2173512&aid=994&area=JP&vst=0
Video info: AKB48 - Bガーデン 中日字幕 (无限狂犬章鱼嘴字幕组)
流畅 29.28MB http://hc.yinyuetai.com/uploads/videos/common/123C01460D36E79BA0CF1EB7801954E1.flv?sc=88d8f21facfd54dc&br=779&vid=2054540&aid=994&area=JP&vst=4
高清 41.34MB http://hd.yinyuetai.com/uploads/videos/common/1828035_hd_409D01460D813B85D457721FDF0BCED7.flv?sc=6146b06d075a55be&br=1099&vid=2054540&aid=994&area=JP&vst=4
超清 85.02MB http://he.yinyuetai.com/uploads/videos/common/1828035_he_94F301460D813B8C82EF7049AE6E3641.flv?sc=93c883b492699e95&br=2261&vid=2054540&aid=994&area=JP&vst=4
Video info: AKB48 - 掌が語ること
流畅 30.17MB http://hc.yinyuetai.com/uploads/videos/common/D32E013DB6069FA9E5669F3C09597C2F.flv?sc=6c517ac82afd9318&br=778&vid=635854&aid=994&area=JP&vst=0
高清 42.55MB http://hd.yinyuetai.com/uploads/videos/common/4A0F013DB616310C06430E9D5B81E6B6.flv?
sc=49b13c96f7977808&br=1097&vid=635854&aid=994&area=JP&vst=0
超清 59.35MB http://he.yinyuetai.com/uploads/videos/common/EBE6013DB61AC60DF68FFAEEE4C636AB.flv?sc=be9cab6dbe2224df&br=1530&vid=635854&aid=994&area=JP&vst=0
Video info: AKB48 - 心のプラカード
流畅 30.51MB http://hc.yinyuetai.com/uploads/videos/common/FD190147A1C4444C727E398C5700C874.flv?sc=f3b134b4663d479b&br=775&vid=2107919&aid=994&area=JP&vst=0
高清 43.04MB http://hd.yinyuetai.com/uploads/videos/common/40D00147A1CB8FBF1A899AA7D7B25843.flv?
sc=19753c38e1e9d692&br=1093&vid=2107919&aid=994&area=JP&vst=0
超清 123.04MB http://he.yinyuetai.com/uploads/videos/common/6E690147A1CB8FC4562EF18A3F4556FF.flv?sc=0a3ff0ebe4b3a5bc&br=3125&vid=2107919&aid=994&area=JP&vst=0
Video info: NMB48 - ドリアン少年
流畅 27.27MB http://hc.yinyuetai.com/uploads/videos/common/478A014E2A12C9521AA21DAE4D69408E.flv?sc=27179278bf4b2b78&br=778&vid=2315990&aid=18043&area=JP&vst=0
高清 38.43MB http://hd.yinyuetai.com/uploads/videos/common/DEB9014E2A23DB3D4227591FCCABD2B9.flv?
sc=922045aa676e156d&br=1096&vid=2315990&aid=18043&area=JP&vst=0
超清 109.58MB http://he.yinyuetai.com/uploads/videos/common/AF97014E2A23DB363107D1FCC7483739.flv?sc=423404a31c08057c&br=3127&vid=2315990&aid=18043&area=JP&vst=0
会员 214.35MB http://sh.yinyuetai.com/uploads/videos/common/970F014E2A23DB2F312EB23D90B716B3.mp4?sc=8ee7e00ee0977f1f&br=6117&vid=2315990&aid=18043&area=JP&vst=0
Video info: AKB48 - Green Flash
流畅 26.96MB http://hc.yinyuetai.com/uploads/videos/common/62B2014D714C60AD12EBE21F23763805.flv?sc=10c559f249b103b2&br=784&vid=2242261&aid=994&area=JP&vst=0
高清 38.05MB http://hd.yinyuetai.com/uploads/videos/common/DD19014D74444ACDA8C892F15E78D849.flv?sc=7b5e74633fe111ff&br=1106&vid=2242261&aid=994&area=JP&vst=0
超清 107.22MB http://he.yinyuetai.com/uploads/videos/common/4BC8014D74444AC78A20BEB44D8FF0C8.flv?
sc=44096ee2d1d16fbe&br=3118&vid=2242261&aid=994&area=JP&vst=0
Video info: NMB48 - イビサガール
流畅 28.08MB http://hc.yinyuetai.com/uploads/videos/common/1CA90146FE9B2A7B98D1E746DA4DA4A3.flv?sc=785e659580d6aa5a&br=778&vid=2086511&aid=18043&area=JP&vst=0
高清 39.59MB http://hd.yinyuetai.com/uploads/videos/common/13210146FEE0FD90E450F63DE2C972A5.flv?sc=8c1883d8fc933027&br=1098&vid=2086511&aid=18043&area=JP&vst=0
超清 102.97MB http://he.yinyuetai.com/uploads/videos/common/13B60146FEE0FD95B8CD43F8BB83B068.flv?
sc=0e846edbd99ee962&br=2856&vid=2086511&aid=18043&area=JP&vst=0
Video info: AKB48 - 真夏のSounds good !
流畅 39.88MB http://hc.yinyuetai.com/uploads/videos/common/F466013AB6C9120E52E98349C292DE47.flv?
sc=bdb53f8b1a31b73b&br=777&vid=398619&aid=994&area=JP&vst=0
高清 56.27MB http://hd.yinyuetai.com/uploads/videos/common/2C65013AD50F006FD35FE181C9551007.flv?sc=9aa6c4fedac1eeeb&br=1096&vid=398619&aid=994&area=JP&vst=0
Video info: NMB48 - らしくない
流畅 296.65MB http://hc.yinyuetai.com/uploads/videos/common/3B930149210B29D2599600DD9BFE0651.flv?sc=0fba620e1635f4c0&br=8234&vid=2157631&aid=18043&area=JP&vst=0
高清 39.55MB http://hd.yinyuetai.com/uploads/videos/common/462501492111EEFA6E4FE56FE7331489.flv?sc=cbeab4fab36f91e2&br=1096&vid=2157631&aid=18043&area=JP&vst=0
超清 112.77MB http://he.yinyuetai.com/uploads/videos/common/8E8901492111EFFC597B3BB1BA60A78F.flv?sc=b81ef8eb309b6918&br=3127&vid=2157631&aid=18043&area=JP&vst=0
Video info: AKB48 - AKB48 SHOW! Ep49 中文字幕 14/11/08 (触角革命字幕组)
流畅 161.69MB http://hc.yinyuetai.com/uploads/videos/common/F2FA0149ABD98A87CB7DE11EF0F2C695.flv?sc=5a83ae29e265a49c&br=779&vid=2180838&aid=994&area=JP&vst=3
高清 228.05MB http://hd.yinyuetai.com/uploads/videos/common/F5D60149ABFE8BF6DB45FE7E4EE5EE89.flv?sc=488453e9ad357568&br=1099&vid=2180838&aid=994&area=JP&vst=3
超清 833.07MB http://he.yinyuetai.com/uploads/videos/common/402F0149ABFE8BFBBDB4627A2B936D39.flv?sc=38e1dd69cc25ba69&br=4015&vid=2180838&aid=994&area=JP&vst=3
Video info: AKB48 - 旅立ちのとき 完整版
流畅 24.33MB http://hc.yinyuetai.com/uploads/videos/common/2E93013AF3FF446A4997C271330CF78A.flv?sc=2a25decbc06c57d6&br=771&vid=545647&aid=994&area=JP&vst=0
高清 34.38MB http://hd.yinyuetai.com/uploads/videos/common/62A2013AF47188150A7C98AAC3F24477.flv?
sc=a1f2f8e22510732f&br=1089&vid=545647&aid=994&area=JP&vst=0
超清 98.58MB http://he.yinyuetai.com/uploads/videos/common/B434013AF4823BDD13EDCB25BB873B92.flv?sc=6ba71b97c71b9d1e&br=3125&vid=545647&aid=994&area=JP&vst=0
Video info: AKB48 - 今日までのメロディー
流畅 82.47MB http://hc.yinyuetai.com/uploads/videos/common/8E7A01460AD9BE849D027A47AA1598D5.flv?
sc=980d5ee1246c78a1&br=778&vid=2054363&aid=994&area=JP&vst=0
高清 116.39MB http://hd.yinyuetai.com/uploads/videos/common/1827834_hd_253B01460B400D6633C0A478EEE914C4.flv?
sc=f536238c27d7b74c&br=1098&vid=2054363&aid=994&area=JP&vst=0
Video info: AKB48 - チューインガムの味がなくなるまで
流畅 22.92MB http://hc.yinyuetai.com/uploads/videos/common/581801480B9C3929162E344080FC89CD.flv?sc=f9547bd05643a731&br=746&vid=2120433&aid=994&area=JP&vst=0
高清 32.34MB http://hd.yinyuetai.com/uploads/videos/common/25CD01480BC7162D6E0DB2052E18747B.flv?sc=8defa622e824f5af&br=1053&vid=2120433&aid=994&area=JP&vst=0
超清 92.11MB http://he.yinyuetai.com/uploads/videos/common/36E301480BC7163282882A4D12724632.flv?sc=844a22abef1a79cb&br=3001&vid=2120433&aid=994&area=JP&vst=0
Video info: AKB48 - ラブラドール.レトリバー 完整版
流畅 35.88MB http://hc.yinyuetai.com/uploads/videos/common/ACA00145B72891160D7ACC896AC944CC.flv?sc=e8d58f0d9086180c&br=775&vid=2043120&aid=994&area=JP&vst=0
高清 50.68MB http://hd.yinyuetai.com/uploads/videos/common/BE350145B74A71A3A39585E2DC896AFB.flv?
sc=338fa04cf03d3005&br=1094&vid=2043120&aid=994&area=JP&vst=0
超清 144.83MB http://he.yinyuetai.com/uploads/videos/common/86860145B751C4007B3F238C2D437DF7.flv?
sc=ba39c9f8f3dfe96a&br=3128&vid=2043120&aid=994&area=JP&vst=0
Video info: AKB48 - 恋するフォーチュンクッキー 完整版
流畅 29.94MB http://hc.yinyuetai.com/uploads/videos/common/DF1B01405442843CF3B18B9B857564AC.flv?
sc=5eb2573e31777b1b&br=777&vid=731559&aid=994&area=JP&vst=0
高清 42.37MB http://hd.yinyuetai.com/uploads/videos/common/D9BA0140544C96595BE5FEA8682D6166.flv?
sc=f7310deec2a8823a&br=1099&vid=731559&aid=994&area=JP&vst=0
超清 120.84MB http://he.yinyuetai.com/uploads/videos/common/C4BF014054512A3BDFD3581FFEFEF0FD.flv?
sc=be3b661f9ff671b7&br=3136&vid=731559&aid=994&area=JP&vst=0
这里是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