test.js 134 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845
  1. // config 替换成自己的桶信息
  2. var config = {
  3. Bucket: 'test-1300555317',
  4. Region: 'ap-beijing',
  5. Uin: '100011913628',
  6. };
  7. QUnit.log(function(details) {
  8. console.log("[test-log]" + JSON.stringify(details));
  9. });
  10. QUnit.done(function(details) {
  11. console.log("[test-result]" + JSON.stringify(details));
  12. });
  13. var util = {
  14. createFile: function (options) {
  15. var buffer = new ArrayBuffer(options.size || 0);
  16. var arr = new Uint8Array(buffer);
  17. for (var i = 0; i < arr.length; i++) {
  18. arr[i] = 0;
  19. }
  20. var opt = {};
  21. options.type && (opt.type = options.type);
  22. var blob = new Blob([buffer], options);
  23. return blob;
  24. },
  25. str2blob: function (str) {
  26. var size = str.length;
  27. var buffer = new ArrayBuffer(size || 0);
  28. var arr = new Uint8Array(buffer);
  29. for (var i = 0; i < arr.length; i++) {
  30. arr[i] = str[i];
  31. }
  32. var blob = new Blob([buffer]);
  33. return blob;
  34. }
  35. };
  36. function camSafeUrlEncode(str) {
  37. return encodeURIComponent(str)
  38. .replace(/!/g, '%21')
  39. .replace(/'/g, '%27')
  40. .replace(/\(/g, '%28')
  41. .replace(/\)/g, '%29')
  42. .replace(/\*/g, '%2A');
  43. }
  44. var getAuthorization = function (options, callback) {
  45. // 格式一、(推荐)后端通过获取临时密钥给到前端,前端计算签名
  46. // 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/
  47. // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk
  48. // var url = '../server/sts.php';
  49. var url = '/sts';
  50. var xhr = new XMLHttpRequest();
  51. xhr.open('GET', url, true);
  52. xhr.onload = function (e) {
  53. try {
  54. var data = JSON.parse(e.target.responseText);
  55. var credentials = data.credentials;
  56. } catch (e) {
  57. }
  58. callback({
  59. TmpSecretId: credentials.tmpSecretId,
  60. TmpSecretKey: credentials.tmpSecretKey,
  61. SecurityToken: credentials.sessionToken,
  62. ExpiredTime: data.expiredTime, // SDK 在 ExpiredTime 时间前,不会再次调用 getAuthorization
  63. });
  64. };
  65. xhr.send();
  66. // // 格式二、(推荐)【细粒度控制权限】后端通过获取临时密钥给到前端,前端只有相同请求才重用临时密钥,后端可以通过 Scope 细粒度控制权限
  67. // // 服务端例子:https://github.com/tencentyun/qcloud-cos-sts-sdk/edit/master/scope.md
  68. // // var url = '../server/sts.php';
  69. // var url = '/sts-scope';
  70. // var xhr = new XMLHttpRequest();
  71. // xhr.open('POST', url, true);
  72. // xhr.setRequestHeader('Content-Type', 'application/json');
  73. // xhr.onload = function (e) {
  74. // try {
  75. // var data = JSON.parse(e.target.responseText);
  76. // var credentials = data.credentials;
  77. // } catch (e) {
  78. // }
  79. // callback({
  80. // TmpSecretId: credentials.tmpSecretId,
  81. // TmpSecretKey: credentials.tmpSecretKey,
  82. // SecurityToken: credentials.sessionToken,
  83. // ExpiredTime: data.expiredTime,
  84. // ScopeLimit: true, // 设为 true 可限制密钥只在相同请求可重用,默认不限制一直可重用,细粒度控制权限需要设为 true
  85. // });
  86. // };
  87. // xhr.send(JSON.stringify(options.Scope));
  88. // // 格式三、(不推荐,分片上传权限不好控制)前端每次请求前都需要通过 getAuthorization 获取签名,后端使用固定密钥或临时密钥计算签名返回给前端
  89. // // 服务端获取签名,请参考对应语言的 COS SDK:https://cloud.tencent.com/document/product/436/6474
  90. // // 注意:这种有安全风险,后端需要通过 method、pathname 严格控制好权限,比如不允许 put / 等
  91. // var method = (options.Method || 'get').toLowerCase();
  92. // var query = options.Query || {};
  93. // var headers = options.Headers || {};
  94. // var pathname = options.Pathname || '/';
  95. // // var url = 'http://127.0.0.1:3000/auth';
  96. // var url = '../server/auth.php';
  97. // var xhr = new XMLHttpRequest();
  98. // var data = {
  99. // method: method,
  100. // pathname: pathname,
  101. // query: query,
  102. // headers: headers,
  103. // };
  104. // xhr.open('POST', url, true);
  105. // xhr.setRequestHeader('content-type', 'application/json');
  106. // xhr.onload = function (e) {
  107. // try {
  108. // var data = JSON.parse(e.target.responseText);
  109. // } catch (e) {
  110. // }
  111. // callback({
  112. // Authorization: data.authorization,
  113. // // SecurityToken: data.sessionToken, // 如果使用临时密钥,需要把 sessionToken 传给 SecurityToken
  114. // });
  115. // };
  116. // xhr.send(JSON.stringify(data));
  117. // // 格式四、(不推荐,适用于前端调试,避免泄露密钥)前端使用固定密钥计算签名,通过 COS.getAuthorization 静态方法计算
  118. // var authorization = COS.getAuthorization({
  119. // SecretId: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // 可传固定密钥或者临时密钥
  120. // SecretKey: 'xxx', // 可传固定密钥或者临时密钥
  121. // Method: options.Method,
  122. // Pathname: options.Pathname,
  123. // Query: options.Query,
  124. // Headers: options.Headers,
  125. // Expires: 900,
  126. // });
  127. // callback({
  128. // Authorization: authorization,
  129. // // SecurityToken: credentials.sessionToken, // 如果使用临时密钥,需要传 SecurityToken
  130. // });
  131. // // 格式五、(不推荐,适用于前端调试,避免泄露密钥)前端使用固定密钥计算签名,通过 cos-auth.js 计算
  132. // var auth = CosAuth({
  133. // Version: '4.0',
  134. // SecretId: 'xxx',
  135. // SecretKey: 'xxx',
  136. // Bucket: config.Bucket,
  137. // Expires: 900,
  138. // Pathname: '/' + (options.Headers && options.Headers['x-cos-copy-source'] ? '' : options.Key),
  139. // });
  140. // callback({Authorization: auth});
  141. };
  142. var dataURItoUploadBody = function (dataURI) {
  143. var byteString = atob(dataURI.split(',')[1]);
  144. var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  145. var ab = new ArrayBuffer(byteString.length);
  146. var ia = new Uint8Array(ab);
  147. for (var i = 0; i < byteString.length; i++) {
  148. ia[i] = byteString.charCodeAt(i);
  149. }
  150. return new Blob([ab], {type: mimeString});
  151. };
  152. var createFileSync = function (size) {
  153. return util.createFile({size: size});
  154. };
  155. var group = function (name, fn) {
  156. return fn();
  157. };
  158. var test = function (name, fn) {
  159. QUnit.test(name, function (assert) {
  160. return new Promise(function (done) {
  161. fn(done, assert);
  162. });
  163. });
  164. };
  165. var request = function (opt, callback) {
  166. var i;
  167. var xhr = new XMLHttpRequest();
  168. xhr.open('GET', opt.url, true);
  169. if (opt.headers) {
  170. for (i in opt.headers) {
  171. if (opt.headers.hasOwnProperty(i)) {
  172. xhr.setRequestHeader(i, opt.headers[i]);
  173. }
  174. }
  175. }
  176. xhr.onload = function (e) {
  177. callback(null, {statusCode: xhr.status}, xhr.responseText);
  178. };
  179. xhr.onerror = function (e) {
  180. callback('error', {statusCode: xhr.status});
  181. };
  182. xhr.send();
  183. };
  184. var cos = new COS({
  185. // 必选参数
  186. getAuthorization: getAuthorization,
  187. // 可选参数
  188. FileParallelLimit: 3, // 控制文件上传并发数
  189. ChunkParallelLimit: 3, // 控制单个文件下分片上传并发数
  190. ChunkSize: 1024 * 1024, // 控制分片大小,单位 B
  191. ProgressInterval: 1, // 控制 onProgress 回调的间隔
  192. ChunkRetryTimes: 3, // 控制文件切片后单片上传失败后重试次数
  193. UploadCheckContentMd5: true, // 上传过程计算 Content-MD5
  194. ForceSignHost: false,
  195. });
  196. var AppId = config.AppId;
  197. var Bucket = config.Bucket;
  198. var BucketShortName = Bucket;
  199. var BucketLongName = Bucket + '-' + AppId;
  200. var TaskId;
  201. var match = config.Bucket.match(/^(.+)-(\d+)$/);
  202. if (match) {
  203. BucketLongName = config.Bucket;
  204. BucketShortName = match[1];
  205. AppId = match[2];
  206. }
  207. function comparePlainObject(a, b) {
  208. if (Object.keys(a).length !== Object.keys(b).length) {
  209. return false;
  210. }
  211. for (var key in a) {
  212. if (typeof a[key] === 'object' && typeof b[key] === 'object') {
  213. if (!comparePlainObject(a[key], b[key])) {
  214. return false;
  215. }
  216. } else if (a[key] != b[key]) {
  217. return false;
  218. }
  219. }
  220. return true;
  221. }
  222. function prepareBigObject(needHeaders) {
  223. return new Promise(function (resolve, reject) {
  224. // 创建测试文件
  225. var filename = name || 'bigger.zip';
  226. var content = util.createFile({size: 1024 * 1024 * 10});
  227. var put = function () {
  228. // 调用方法
  229. var params = {
  230. Bucket: config.Bucket,
  231. Region: config.Region,
  232. Key: filename,
  233. Body: content,
  234. ContentLength: content.length,
  235. };
  236. if (needHeaders) {
  237. params.ContentType = 'text/html';
  238. params.CacheControl = 'max-age=7200';
  239. params.ContentDisposition = 'inline;filename=hello.jpg';
  240. params.Expires = (new Date()).toGMTString();
  241. params.Headers = {
  242. 'x-cos-meta-test': 'xxx'
  243. };
  244. }
  245. cos.putObject(params, function (err, data) {
  246. err ? reject(err) : resolve()
  247. });
  248. };
  249. put();
  250. });
  251. }
  252. function prepareBucket() {
  253. return new Promise(function (resolve, reject) {
  254. resolve();
  255. });
  256. }
  257. group('mock readAsBinaryString', function () {
  258. test('mock readAsBinaryString', function (done, assert) {
  259. FileReader.prototype._readAsBinaryString = FileReader.prototype.readAsBinaryString;
  260. FileReader.prototype.readAsBinaryString = false;
  261. var filename = '10m.zip';
  262. var blob = util.createFile({size: 1024 * 1024 * 10});
  263. var paused = false;
  264. cos.sliceUploadFile({
  265. Bucket: config.Bucket,
  266. Region: config.Region,
  267. Key: filename,
  268. Body: blob,
  269. onTaskReady: function (taskId) {
  270. TaskId = taskId;
  271. },
  272. onProgress: function (info) {
  273. if (!paused && info.percent > 0.6) {
  274. cos.cancelTask(TaskId);
  275. var hasProgress = false;
  276. cos.sliceUploadFile({
  277. Bucket: config.Bucket,
  278. Region: config.Region,
  279. Key: filename,
  280. Body: blob,
  281. onTaskReady: function (taskId) {
  282. TaskId = taskId;
  283. },
  284. onProgress: function (info) {
  285. if (info.percent === 0) return;
  286. assert.ok(info.percent > 0.3, '分片续传成功');
  287. cos.cancelTask(TaskId);
  288. FileReader.prototype.readAsBinaryString = FileReader.prototype._readAsBinaryString;
  289. delete FileReader.prototype._readAsBinaryString;
  290. done();
  291. }
  292. }, function (err) {
  293. if (hasProgress) {
  294. assert.ok(false, '分片续传');
  295. done();
  296. }
  297. });
  298. }
  299. }
  300. });
  301. });
  302. });
  303. group('getAuth()', function () {
  304. test('getAuth()', function (done, assert) {
  305. var content = Date.now().toString();
  306. var key = '1.txt';
  307. cos.putObject({
  308. Bucket: config.Bucket,
  309. Region: config.Region,
  310. Key: key,
  311. Body: content,
  312. }, function (err, data) {
  313. cos.options.getAuthorization({
  314. Method: 'get',
  315. Key: key,
  316. Scope: [{
  317. action: 'GetObject',
  318. bucket: config.Bucket,
  319. region: config.Region,
  320. prefix: key,
  321. }],
  322. }, function (AuthData) {
  323. if (typeof AuthData === 'string') {
  324. AuthData = {Authorization: AuthData};
  325. }
  326. if (!AuthData.Authorization) {
  327. AuthData.Authorization = COS.getAuthorization({
  328. SecretId: AuthData.TmpSecretId,
  329. SecretKey: AuthData.TmpSecretKey,
  330. Method: 'get',
  331. Key: key,
  332. SystemClockOffset: cos.options.SystemClockOffset,
  333. });
  334. }
  335. var link = 'http://' + config.Bucket + '.cos.' + config.Region + '.myqcloud.com' + '/' +
  336. camSafeUrlEncode(key).replace(/%2F/g, '/') + '?' + AuthData.Authorization +
  337. (AuthData.SecurityToken ? '&x-cos-security-token=' + AuthData.SecurityToken : '');
  338. request({
  339. url: link,
  340. }, function (err, response, body) {
  341. assert.ok(response.statusCode === 200);
  342. assert.ok(body === content);
  343. done();
  344. });
  345. });
  346. });
  347. });
  348. });
  349. group('getObjectUrl()', function () {
  350. test('getObjectUrl()', function (done, assert) {
  351. var content = Date.now().toString();
  352. var key = '1.txt';
  353. cos.putObject({
  354. Bucket: config.Bucket,
  355. Region: config.Region,
  356. Key: key,
  357. Body: content,
  358. }, function (err, data) {
  359. cos.getObjectUrl({
  360. Bucket: config.Bucket,
  361. Region: config.Region,
  362. Key: key,
  363. }, function (err, data) {
  364. request({
  365. url: data.Url,
  366. }, function (err, response, body) {
  367. assert.ok(!err, '文件获取出错');
  368. assert.ok(response.statusCode === 200, '获取文件 200');
  369. assert.ok(body.toString() === content, '通过获取签名能正常获取文件');
  370. done();
  371. });
  372. });
  373. });
  374. });
  375. });
  376. group('auth check', function () {
  377. test('auth check', function (done, assert) {
  378. cos.getBucket({
  379. Bucket: config.Bucket,
  380. Region: config.Region,
  381. Prefix: 'aksjhdlash sajlhj!@#$%^&*()_+=-[]{}\';:"/.<>?.,??sadasd#/.,/~`',
  382. Headers: {
  383. 'x-cos-test': 'aksjhdlash sajlhj!@#$%^&*()_+=-[]{}\';:\"/.<>?.,??sadasd#/.,/~`',
  384. },
  385. }, function (err, data) {
  386. assert.ok(!err);
  387. done();
  388. });
  389. });
  390. });
  391. group('getBucket(),listObjectVersions', function () {
  392. test('正常获取 bucket 里的文件列表', function (done, assert) {
  393. prepareBucket().then(function () {
  394. cos.getBucket({
  395. Bucket: config.Bucket,
  396. Region: config.Region
  397. }, function (err, data) {
  398. assert.ok(data.Name === BucketLongName);
  399. assert.ok(data.Contents.constructor, Array);
  400. done();
  401. });
  402. }).catch(function () {
  403. assert.ok(false);
  404. done();
  405. });
  406. });
  407. test('正常获取 bucket 里的文件版本列表', function (done, assert) {
  408. prepareBucket().then(function () {
  409. cos.listObjectVersions({
  410. Bucket: config.Bucket,
  411. Region: config.Region
  412. }, function (err, data) {
  413. assert.ok(data.Name === BucketLongName);
  414. assert.ok(data.Versions.constructor === Array);
  415. done();
  416. });
  417. }).catch(function () {
  418. assert.ok(false);
  419. done();
  420. });
  421. });
  422. });
  423. group('putObject(),cancelTask()', function () {
  424. test('putObject(),cancelTask()', function (done, assert) {
  425. var filename = '10m.zip';
  426. var alive = false;
  427. var canceled = false;
  428. cos.putObject({
  429. Bucket: config.Bucket,
  430. Region: config.Region,
  431. Key: filename,
  432. Body: util.createFile({size: 1024 * 1024 * 10}),
  433. onTaskReady: function (taskId) {
  434. TaskId = taskId;
  435. },
  436. onProgress: function (info) {
  437. alive = true;
  438. if (!canceled) {
  439. cos.cancelTask(TaskId);
  440. alive = false;
  441. canceled = true;
  442. setTimeout(function () {
  443. assert.ok(!alive, '取消上传已经生效');
  444. done();
  445. }, 1200);
  446. }
  447. }
  448. }, function (err, data) {
  449. alive = true;
  450. });
  451. });
  452. });
  453. group('sliceUploadFile() 完整上传文件', function () {
  454. test('sliceUploadFile() 完整上传文件', function (done, assert) {
  455. var lastPercent;
  456. var filename = '3m.zip';
  457. var fileSize = 1024 * 1024 * 3;
  458. var blob = createFileSync(fileSize)
  459. cos.abortUploadTask({
  460. Bucket: config.Bucket,
  461. Region: config.Region,
  462. Key: filename,
  463. Level: 'file',
  464. }, function (err, data) {
  465. cos.sliceUploadFile({
  466. Bucket: config.Bucket,
  467. Region: config.Region,
  468. Key: filename,
  469. Body: blob,
  470. onTaskReady: function (taskId) {
  471. TaskId = taskId;
  472. },
  473. onProgress: function (info) {
  474. lastPercent = info.percent;
  475. }
  476. }, function (err, data) {
  477. assert.ok(data.ETag.length > 0);
  478. cos.headObject({
  479. Bucket: config.Bucket,
  480. Region: config.Region,
  481. Key: filename,
  482. }, function (err, data) {
  483. assert.ok(data && data.headers && data.headers.etag && data.headers.etag.length > 0, '文件已上传成功');
  484. assert.ok(data && data.headers && parseInt(data.headers['content-length'] || 0) === fileSize, '文件大小一致');
  485. done();
  486. });
  487. });
  488. });
  489. });
  490. test('sliceUploadFile(),pauseTask(),restartTask()', function (done, assert) {
  491. var filename = '10m.zip';
  492. var blob = util.createFile({size: 1024 * 1024 * 10});
  493. var paused = false;
  494. var restarted = false;
  495. cos.abortUploadTask({
  496. Bucket: config.Bucket,
  497. Region: config.Region,
  498. Key: filename,
  499. Level: 'file',
  500. }, function (err, data) {
  501. var TaskId;
  502. cos.sliceUploadFile({
  503. Bucket: config.Bucket,
  504. Region: config.Region,
  505. Key: filename,
  506. Body: blob,
  507. onTaskReady: function (taskId) {
  508. TaskId = taskId;
  509. },
  510. onProgress: function (info) {
  511. if (!paused && info.percent > 0.6) {
  512. cos.pauseTask(TaskId);
  513. paused = true;
  514. setTimeout(function () {
  515. restarted = true;
  516. cos.restartTask(TaskId);
  517. }, 1000);
  518. }
  519. if (paused && restarted) {
  520. if (info.percent === 0) return;
  521. assert.ok(info.percent > 0.3, '暂停和重试成功');
  522. cos.cancelTask(TaskId);
  523. done();
  524. }
  525. }
  526. }, function (err, data) {
  527. paused = true;
  528. });
  529. });
  530. });
  531. test('sliceUploadFile(),cancelTask(),restartTask()', function (done, assert) {
  532. var filename = '10m.zip';
  533. var blob = util.createFile({size: 1024 * 1024 * 3});
  534. var paused = false;
  535. cos.abortUploadTask({
  536. Bucket: config.Bucket,
  537. Region: config.Region,
  538. Key: filename,
  539. Level: 'file',
  540. }, function (err, data) {
  541. var TaskId;
  542. cos.sliceUploadFile({
  543. Bucket: config.Bucket,
  544. Region: config.Region,
  545. Key: filename,
  546. Body: blob,
  547. onTaskReady: function (taskId) {
  548. TaskId = taskId;
  549. },
  550. onProgress: function (info) {
  551. if (!paused && info.percent > 0.6) {
  552. cos.cancelTask(TaskId);
  553. setTimeout(function () {
  554. cos.sliceUploadFile({
  555. Bucket: config.Bucket,
  556. Region: config.Region,
  557. Key: filename,
  558. Body: blob,
  559. }, function (err, data) {
  560. assert.ok(!err);
  561. done();
  562. });
  563. }, 10);
  564. }
  565. }
  566. }, function (err, data) {
  567. });
  568. });
  569. });
  570. test('sliceUploadFile(),cancelTask()', function (done, assert) {
  571. var filename = '3m.zip';
  572. var alive = false;
  573. var canceled = false;
  574. cos.sliceUploadFile({
  575. Bucket: config.Bucket,
  576. Region: config.Region,
  577. Key: filename,
  578. Body: util.createFile({size: 1024 * 1024 * 3}),
  579. onTaskReady: function (taskId) {
  580. TaskId = taskId;
  581. },
  582. onProgress: function (info) {
  583. alive = true;
  584. if (!canceled) {
  585. cos.cancelTask(TaskId);
  586. alive = false;
  587. canceled = true;
  588. setTimeout(function () {
  589. assert.ok(!alive, '取消上传已经生效');
  590. done();
  591. }, 1200);
  592. }
  593. }
  594. }, function (err, data) {
  595. alive = true;
  596. });
  597. });
  598. });
  599. group('abortUploadTask()', function () {
  600. test('abortUploadTask(),Level=task', function (done, assert) {
  601. var filename = '1m.zip';
  602. cos.multipartInit({
  603. Bucket: config.Bucket,
  604. Region: config.Region,
  605. Key: filename,
  606. }, function (err, data) {
  607. cos.abortUploadTask({
  608. Bucket: config.Bucket,
  609. Region: config.Region,
  610. Key: filename,
  611. Level: 'task',
  612. UploadId: data.UploadId,
  613. }, function (err, data) {
  614. var nameExist = false;
  615. data.successList.forEach(function (item) {
  616. if (filename === item.Key) {
  617. nameExist = true;
  618. }
  619. });
  620. assert.ok(data.successList.length >= 1, '成功取消单个分片任务');
  621. assert.ok(nameExist, '成功取消单个分片任务');
  622. done();
  623. });
  624. });
  625. });
  626. test('abortUploadTask(),Level=file', function (done, assert) {
  627. var filename = '1m.zip';
  628. var blob = util.createFile({size: 1024 * 1024});
  629. cos.sliceUploadFile({
  630. Bucket: config.Bucket,
  631. Region: config.Region,
  632. Key: filename,
  633. Body: blob,
  634. onTaskReady: function (taskId) {
  635. TaskId = taskId;
  636. },
  637. onProgress: function (info) {
  638. cos.cancelTask(TaskId);
  639. cos.abortUploadTask({
  640. Bucket: config.Bucket,
  641. Region: config.Region,
  642. Level: 'file',
  643. Key: filename,
  644. }, function (err, data) {
  645. assert.ok(data.successList.length >= 1, '成功舍弃单个文件下的所有分片任务');
  646. assert.ok(data.successList[0] && data.successList[0].Key === filename, '成功舍弃单个文件的所有分片任务');
  647. done();
  648. });
  649. }
  650. });
  651. });
  652. test('abortUploadTask(),Level=bucket', function (done, assert) {
  653. var filename = '1m.zip';
  654. var blob = util.createFile({size: 1024 * 1024 * 10});
  655. cos.sliceUploadFile({
  656. Bucket: config.Bucket,
  657. Region: config.Region,
  658. Key: filename,
  659. Body: blob,
  660. onTaskReady: function (taskId) {
  661. TaskId = taskId;
  662. },
  663. onProgress: function (info) {
  664. cos.cancelTask(TaskId);
  665. cos.abortUploadTask({
  666. Bucket: config.Bucket,
  667. Region: config.Region,
  668. Level: 'bucket',
  669. }, function (err, data) {
  670. var nameExist = false;
  671. data.successList.forEach(function (item) {
  672. if (filename === item.Key) {
  673. nameExist = true;
  674. }
  675. });
  676. assert.ok(data.successList.length >= 1, '成功舍弃Bucket下所有分片任务');
  677. assert.ok(nameExist, '成功舍弃Bucket下所有分片任务');
  678. done();
  679. });
  680. }
  681. });
  682. });
  683. });
  684. group('headBucket()', function () {
  685. test('headBucket()', function (done, assert) {
  686. cos.headBucket({
  687. Bucket: config.Bucket,
  688. Region: config.Region
  689. }, function (err, data) {
  690. assert.ok(data, '正常获取 head bucket');
  691. done();
  692. });
  693. });
  694. test('headBucket() not exist', function (done, assert) {
  695. cos.headBucket({
  696. Bucket: config.Bucket + Date.now().toString(36),
  697. Region: config.Region
  698. }, function (err, data) {
  699. assert.ok(err, 'bucket 不存在');
  700. done();
  701. });
  702. });
  703. test('deleteBucket()', function (done, assert) {
  704. cos.deleteBucket({
  705. Bucket: config.Bucket + Date.now().toString(36),
  706. Region: config.Region
  707. }, function (err, data) {
  708. assert.ok(err, '正常获取 head bucket');
  709. done();
  710. });
  711. });
  712. test('getBucket()', function (done, assert) {
  713. cos.getBucket({
  714. Bucket: config.Bucket,
  715. Region: config.Region
  716. }, function (err, data) {
  717. assert.ok(data.Name === BucketLongName, '能列出 bucket');
  718. assert.ok(data.Contents.constructor === Array, '正常获取 bucket 里的文件列表');
  719. done();
  720. });
  721. });
  722. });
  723. group('putObject()', function () {
  724. var buf = new ArrayBuffer(8);
  725. var arr = new Uint8Array(buf);
  726. [0x89, 0xe8,0xaf,0xb4,0x2e,0x70,0x72,0x70,0x72].forEach(function (v, i) {
  727. arr[i] = v;
  728. });
  729. test('putObject()', function (done, assert) {
  730. var filename = '1.txt';
  731. var getObjectETag = function (callback) {
  732. setTimeout(function () {
  733. cos.headObject({
  734. Bucket: config.Bucket,
  735. Region: config.Region,
  736. Key: filename,
  737. }, function (err, data) {
  738. callback(data && data.headers && data.headers.etag);
  739. });
  740. }, 2000);
  741. };
  742. var content = Date.now().toString();
  743. var lastPercent = 0;
  744. cos.putObject({
  745. Bucket: config.Bucket,
  746. Region: config.Region,
  747. Key: filename,
  748. Body: util.str2blob(content),
  749. onProgress: function (info) {
  750. lastPercent = info.percent;
  751. },
  752. }, function (err, data) {
  753. if (err) throw err;
  754. assert.ok(data && data.ETag, 'putObject 有返回 ETag');
  755. getObjectETag(function (ETag) {
  756. assert.ok(data.ETag === ETag, 'Blob 创建 object');
  757. done();
  758. });
  759. });
  760. });
  761. test('putObject(),string', function (done, assert) {
  762. var filename = '1.txt';
  763. var content = '中文_' + Date.now().toString(36);
  764. var lastPercent = 0;
  765. cos.putObject({
  766. Bucket: config.Bucket,
  767. Region: config.Region,
  768. Key: filename,
  769. Body: content,
  770. onProgress: function (info) {
  771. lastPercent = info.percent;
  772. },
  773. }, function (err, data) {
  774. if (err) throw err;
  775. var ETag = data && data.ETag;
  776. assert.ok(ETag, 'putObject 有返回 ETag');
  777. cos.getObject({
  778. Bucket: config.Bucket,
  779. Region: config.Region,
  780. Key: filename,
  781. }, function (err, data) {
  782. assert.ok(data.Body && data.Body === content && (data.headers && data.headers.etag) === ETag);
  783. done();
  784. });
  785. });
  786. });
  787. test('putObject(),string,empty', function (done, assert) {
  788. var content = '';
  789. var lastPercent = 0;
  790. var Key = '1.txt';
  791. cos.putObject({
  792. Bucket: config.Bucket,
  793. Region: config.Region,
  794. Key: Key,
  795. Body: content,
  796. onProgress: function (info) {
  797. lastPercent = info.percent;
  798. },
  799. }, function (err, data) {
  800. if (err) throw err;
  801. var ETag = data && data.ETag;
  802. assert.ok(ETag, 'putObject 有返回 ETag');
  803. cos.getObject({
  804. Bucket: config.Bucket,
  805. Region: config.Region,
  806. Key: Key,
  807. }, function (err, data) {
  808. assert.ok(data.Body === content && (data.headers && data.headers.etag) === ETag);
  809. done();
  810. });
  811. });
  812. });
  813. test('putObject(),特殊二进制字符 ArrayBuffer md5', function (done, assert) {
  814. var content = '';
  815. var lastPercent = 0;
  816. var Key = '1.mp4';
  817. var blob = new Blob([buf]);
  818. cos.putObject({
  819. Bucket: config.Bucket,
  820. Region: config.Region,
  821. Key: Key,
  822. Body: blob,
  823. onProgress: function (info) {
  824. lastPercent = info.percent;
  825. },
  826. }, function (err, data) {
  827. if (err) throw err;
  828. var ETag = data && data.ETag;
  829. assert.ok(ETag, 'putObject 有返回 ETag');
  830. cos.getObject({
  831. Bucket: config.Bucket,
  832. Region: config.Region,
  833. Key: Key,
  834. BodyType: 'arraybuffer',
  835. }, function (err, data) {
  836. var arr = new Uint8Array(data.Body);
  837. var isSame = arr.every(function (v, i) {
  838. return v === arr[i];
  839. });
  840. assert.ok(isSame && (data.headers && data.headers.etag) === ETag);
  841. done();
  842. });
  843. });
  844. });
  845. test('putObject(),特殊二进制字符 Blob md5', function (done, assert) {
  846. var content = '';
  847. var lastPercent = 0;
  848. var Key = '1.mp4';
  849. cos.putObject({
  850. Bucket: config.Bucket,
  851. Region: config.Region,
  852. Key: Key,
  853. Body: buf,
  854. onProgress: function (info) {
  855. lastPercent = info.percent;
  856. },
  857. }, function (err, data) {
  858. if (err) throw err;
  859. var ETag = data && data.ETag;
  860. assert.ok(ETag, 'putObject 有返回 ETag');
  861. cos.getObject({
  862. Bucket: config.Bucket,
  863. Region: config.Region,
  864. Key: Key,
  865. BodyType: 'arraybuffer',
  866. }, function (err, data) {
  867. var arr = new Uint8Array(data.Body);
  868. var isSame = arr.every(function (v, i) {
  869. return v === arr[i];
  870. });
  871. assert.ok(isSame && (data.headers && data.headers.etag) === ETag);
  872. done();
  873. });
  874. });
  875. });
  876. test('putObject(),特殊二进制字符 中文 string md5', function (done, assert) {
  877. var Key = '1.txt';
  878. var content = '中文';
  879. cos.putObject({
  880. Bucket: config.Bucket,
  881. Region: config.Region,
  882. Key: Key,
  883. Body: content,
  884. }, function (err, data) {
  885. if (err) throw err;
  886. var ETag = data && data.ETag;
  887. assert.ok(ETag, 'putObject 有返回 ETag');
  888. cos.getObject({
  889. Bucket: config.Bucket,
  890. Region: config.Region,
  891. Key: Key,
  892. }, function (err, data) {
  893. var isSame = content === data.Body;
  894. assert.ok(isSame && (data.headers && data.headers.etag) === ETag);
  895. done();
  896. });
  897. });
  898. });
  899. test('putObject(),特殊二进制字符 unescape string md5', function (done, assert) {
  900. var Key = '1.txt';
  901. var content = unescape(encodeURIComponent('中文'));
  902. cos.putObject({
  903. Bucket: config.Bucket,
  904. Region: config.Region,
  905. Key: Key,
  906. Body: content,
  907. }, function (err, data) {
  908. if (err) throw err;
  909. var ETag = data && data.ETag;
  910. assert.ok(ETag, 'putObject 有返回 ETag');
  911. cos.getObject({
  912. Bucket: config.Bucket,
  913. Region: config.Region,
  914. Key: Key,
  915. }, function (err, data) {
  916. var isSame = content === data.Body;
  917. assert.ok(isSame && (data.headers && data.headers.etag) === ETag);
  918. done();
  919. });
  920. });
  921. });
  922. });
  923. group('getObject()', function () {
  924. test('getObject() body', function (done, assert) {
  925. var key = '1.txt';
  926. var content = Date.now().toString();
  927. cos.putObject({
  928. Bucket: config.Bucket,
  929. Region: config.Region,
  930. Key: key,
  931. Body: content,
  932. }, function (err, data) {
  933. cos.getObject({
  934. Bucket: config.Bucket,
  935. Region: config.Region,
  936. Key: key
  937. }, function (err, data) {
  938. if (err) throw err;
  939. var objectContent = data.Body.toString();
  940. assert.ok(data.headers['content-length'] === '' + content.length);
  941. assert.ok(objectContent === content);
  942. done();
  943. });
  944. });
  945. });
  946. test('getObject() DataType blob', function (done, assert) {
  947. var key = '1.txt';
  948. var content = Date.now().toString();
  949. cos.putObject({
  950. Bucket: config.Bucket,
  951. Region: config.Region,
  952. Key: key,
  953. Body: content,
  954. }, function (err, data) {
  955. cos.getObject({
  956. Bucket: config.Bucket,
  957. Region: config.Region,
  958. Key: key,
  959. DataType: 'blob',
  960. }, function (err, data) {
  961. if (err) throw err;
  962. assert.ok(data.Body instanceof Blob);
  963. assert.ok(data.headers['content-length'] === '' + content.length);
  964. done();
  965. });
  966. });
  967. });
  968. test('getObject() DataType arraybuffer', function (done, assert) {
  969. var key = '1.txt';
  970. var content = Date.now().toString();
  971. cos.putObject({
  972. Bucket: config.Bucket,
  973. Region: config.Region,
  974. Key: key,
  975. Body: content,
  976. }, function (err, data) {
  977. cos.getObject({
  978. Bucket: config.Bucket,
  979. Region: config.Region,
  980. Key: key,
  981. DataType: 'arraybuffer',
  982. }, function (err, data) {
  983. if (err) throw err;
  984. assert.ok(data.Body instanceof ArrayBuffer);
  985. assert.ok(data.headers['content-length'] === '' + content.length);
  986. done();
  987. });
  988. });
  989. });
  990. });
  991. group('Key 特殊字符', function () {
  992. test('Key 特殊字符', function (done, assert) {
  993. cos.putObject({
  994. Bucket: config.Bucket,
  995. Region: config.Region,
  996. Key: '(!\'*) "#$%&+,-./0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
  997. Body: Date.now().toString()
  998. }, function (err, data) {
  999. if (err) throw err;
  1000. assert.ok(data, 'putObject 特殊字符的 Key 能通过');
  1001. done();
  1002. });
  1003. });
  1004. });
  1005. group('putObjectCopy() 1', function () {
  1006. test('putObjectCopy() 1', function (done, assert) {
  1007. var content = Date.now().toString(36);
  1008. cos.putObject({
  1009. Bucket: config.Bucket,
  1010. Region: config.Region,
  1011. Key: '1.txt',
  1012. Body: content,
  1013. }, function (err, data) {
  1014. var ETag = data.ETag;
  1015. cos.deleteObject({
  1016. Bucket: config.Bucket,
  1017. Region: config.Region,
  1018. Key: '1.copy.txt',
  1019. }, function (err, data) {
  1020. cos.putObjectCopy({
  1021. Bucket: config.Bucket,
  1022. Region: config.Region,
  1023. Key: '1.copy.txt',
  1024. CopySource: BucketLongName + '.cos.' + config.Region + '.myqcloud.com/1.txt',
  1025. }, function (err, data) {
  1026. cos.headObject({
  1027. Bucket: config.Bucket,
  1028. Region: config.Region,
  1029. Key: '1.copy.txt',
  1030. }, function (err, data) {
  1031. assert.ok(data.headers && data.headers.etag === ETag, '成功复制文件');
  1032. done();
  1033. });
  1034. });
  1035. });
  1036. });
  1037. });
  1038. });
  1039. group('putObjectCopy()', function () {
  1040. var filename = '1.txt';
  1041. test('正常复制 object', function (done, assert) {
  1042. cos.putObjectCopy({
  1043. Bucket: config.Bucket,
  1044. Region: config.Region,
  1045. Key: '1.copy.txt',
  1046. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/' + filename,
  1047. }, function (err, data) {
  1048. assert.ok(!err);
  1049. assert.ok(data.ETag.length > 0);
  1050. done();
  1051. });
  1052. });
  1053. test('捕获 object 异常', function (done, assert) {
  1054. var errFileName = '12345.txt';
  1055. cos.putObjectCopy({
  1056. Bucket: config.Bucket,
  1057. Region: config.Region,
  1058. Key: '1.copy.txt',
  1059. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/' + errFileName,
  1060. }, function (err, data) {
  1061. assert.equal(true, err.statusCode === 404);
  1062. assert.equal(true, err.error.Code === 'NoSuchKey')
  1063. done();
  1064. });
  1065. });
  1066. });
  1067. group('sliceCopyFile()', function () {
  1068. var filename = 'bigger.zip';
  1069. var Key = 'bigger.copy.zip';
  1070. test('正常分片复制 object', function (done, assert) {
  1071. prepareBigObject(true).then(function () {
  1072. cos.headObject({
  1073. Bucket: config.Bucket,
  1074. Region: config.Region,
  1075. Key: filename,
  1076. }, function (err, data1) {
  1077. if (err) throw err;
  1078. cos.sliceCopyFile({
  1079. Bucket: config.Bucket,
  1080. Region: config.Region,
  1081. Key: Key,
  1082. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/'+ filename,
  1083. CopySliceSize: 5 * 1024 * 1024,
  1084. },function (err, data) {
  1085. if (err) throw err;
  1086. assert.ok(data.ETag.length > 0);
  1087. cos.headObject({
  1088. Bucket: config.Bucket,
  1089. Region: config.Region,
  1090. Key: Key,
  1091. }, function (err, data2) {
  1092. if (err) throw err;
  1093. delete data1.VersionId;
  1094. delete data2.VersionId;
  1095. delete data1.headers['x-cos-request-id'];
  1096. delete data2.headers['x-cos-request-id'];
  1097. delete data1.headers['x-cos-version-id'];
  1098. delete data2.headers['x-cos-version-id'];
  1099. delete data1.headers['x-cos-replication-status'];
  1100. delete data2.headers['x-cos-replication-status'];
  1101. delete data1.headers['last-modified'];
  1102. delete data2.headers['last-modified'];
  1103. delete data1.headers['date'];
  1104. delete data2.headers['date'];
  1105. delete data1.headers['etag'];
  1106. delete data2.headers['etag'];
  1107. delete data1.ETag;
  1108. delete data2.ETag;
  1109. delete data1.RequestId;
  1110. delete data2.RequestId;
  1111. assert.ok(comparePlainObject(data1, data2));
  1112. done();
  1113. });
  1114. });
  1115. });
  1116. }).catch(function () {
  1117. assert.ok(false);
  1118. done();
  1119. });
  1120. });
  1121. test('单片复制 object', function (done, assert) {
  1122. setTimeout(function () {
  1123. prepareBigObject(true).then(function () {
  1124. cos.headObject({
  1125. Bucket: config.Bucket,
  1126. Region: config.Region,
  1127. Key: filename,
  1128. }, function (err, data1) {
  1129. if (err) throw err;
  1130. cos.sliceCopyFile({
  1131. Bucket: config.Bucket,
  1132. Region: config.Region,
  1133. Key: Key,
  1134. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/' + filename,
  1135. SliceSize: 10 * 1024 * 1024,
  1136. }, function (err, data) {
  1137. if (err) throw err;
  1138. assert.ok(data.ETag.length > 0);
  1139. setTimeout(function () {
  1140. cos.headObject({
  1141. Bucket: config.Bucket,
  1142. Region: config.Region,
  1143. Key: Key,
  1144. }, function (err, data2) {
  1145. if (err) throw err;
  1146. delete data1.VersionId;
  1147. delete data2.VersionId;
  1148. delete data1.headers['x-cos-request-id'];
  1149. delete data2.headers['x-cos-request-id'];
  1150. delete data1.headers['x-cos-version-id'];
  1151. delete data2.headers['x-cos-version-id'];
  1152. delete data1.headers['x-cos-replication-status'];
  1153. delete data2.headers['x-cos-replication-status'];
  1154. delete data1.headers['last-modified'];
  1155. delete data2.headers['last-modified'];
  1156. delete data1.headers['date'];
  1157. delete data2.headers['date'];
  1158. delete data1.ETag;
  1159. delete data2.ETag;
  1160. delete data1.RequestId;
  1161. delete data2.RequestId;
  1162. assert.ok(comparePlainObject(data1, data2));
  1163. done();
  1164. });
  1165. }, 2000);
  1166. });
  1167. });
  1168. }).catch(function () {
  1169. assert.ok(false);
  1170. done();
  1171. });
  1172. }, 2000);
  1173. });
  1174. test('CopySource nor found', function (done, assert) {
  1175. cos.sliceCopyFile({
  1176. Bucket: config.Bucket,
  1177. Region: config.Region,
  1178. Key: Key,
  1179. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/' + Date.now(),
  1180. }, function (err, data) {
  1181. assert.ok(err);
  1182. done();
  1183. });
  1184. });
  1185. test('复制归档文件', function (done, assert) {
  1186. var sourceKey = Date.now().toString(36);
  1187. cos.putObject({
  1188. Bucket: config.Bucket,
  1189. Region: config.Region,
  1190. Key: sourceKey,
  1191. StorageClass: 'ARCHIVE',
  1192. }, function () {
  1193. cos.sliceCopyFile({
  1194. Bucket: config.Bucket,
  1195. Region: config.Region,
  1196. Key: Key,
  1197. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/' + sourceKey,
  1198. }, function (err, data) {
  1199. assert.ok(err);
  1200. done();
  1201. });
  1202. });
  1203. });
  1204. });
  1205. group('deleteMultipleObject', function () {
  1206. test('deleteMultipleObject()', function (done, assert) {
  1207. var content = Date.now().toString(36);
  1208. cos.putObject({
  1209. Bucket: config.Bucket,
  1210. Region: config.Region,
  1211. Key: '1.txt',
  1212. Body: content,
  1213. }, function (err, data) {
  1214. cos.putObject({
  1215. Bucket: config.Bucket,
  1216. Region: config.Region,
  1217. Key: '2.txt',
  1218. Body: content,
  1219. }, function (err, data) {
  1220. cos.deleteMultipleObject({
  1221. Bucket: config.Bucket,
  1222. Region: config.Region,
  1223. Objects: [
  1224. {Key: '1.txt'},
  1225. {Key: '2.txt'},
  1226. ],
  1227. }, function (err, data) {
  1228. assert.ok(data.Deleted.length === 2);
  1229. cos.headObject({
  1230. Bucket: config.Bucket,
  1231. Region: config.Region,
  1232. Key: '1.txt',
  1233. }, function (err, data) {
  1234. assert.ok(err.statusCode === 404, '1.txt 删除成功');
  1235. cos.headObject({
  1236. Bucket: config.Bucket,
  1237. Region: config.Region,
  1238. Key: '2.txt',
  1239. }, function (err, data) {
  1240. assert.ok(err.statusCode === 404, '2.txt 删除成功');
  1241. done();
  1242. });
  1243. });
  1244. });
  1245. });
  1246. });
  1247. });
  1248. });
  1249. group('BucketAcl', function () {
  1250. var AccessControlPolicy = {
  1251. "Owner": {
  1252. "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
  1253. },
  1254. "Grants": [{
  1255. "Grantee": {
  1256. "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
  1257. },
  1258. "Permission": "READ"
  1259. }]
  1260. };
  1261. var AccessControlPolicy2 = {
  1262. "Owner": {
  1263. "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
  1264. },
  1265. "Grant": {
  1266. "Grantee": {
  1267. "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
  1268. },
  1269. "Permission": "READ"
  1270. }
  1271. };
  1272. test('putBucketAcl() header ACL:private', function (done, assert) {
  1273. cos.putBucketAcl({
  1274. Bucket: config.Bucket,
  1275. Region: config.Region,
  1276. ACL: 'private'
  1277. }, function (err, data) {
  1278. assert.ok(!err, 'putBucketAcl 成功');
  1279. cos.getBucketAcl({
  1280. Bucket: config.Bucket,
  1281. Region: config.Region
  1282. }, function (err, data) {
  1283. AccessControlPolicy.Owner.ID = data.Owner.ID;
  1284. AccessControlPolicy2.Owner.ID = data.Owner.ID;
  1285. assert.ok(data.ACL === 'private' || data.ACL === 'default');
  1286. done();
  1287. });
  1288. });
  1289. });
  1290. test('putBucketAcl() header ACL:public-read', function (done, assert) {
  1291. cos.putBucketAcl({
  1292. Bucket: config.Bucket,
  1293. Region: config.Region,
  1294. ACL: 'public-read',
  1295. }, function (err, data) {
  1296. assert.ok(!err, 'putBucketAcl 成功');
  1297. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1298. assert.ok(data.ACL === 'public-read');
  1299. done();
  1300. });
  1301. });
  1302. });
  1303. test('putBucketAcl() header ACL:public-read-write', function (done, assert) {
  1304. cos.putBucketAcl({
  1305. Bucket: config.Bucket,
  1306. Region: config.Region,
  1307. ACL: 'public-read-write',
  1308. }, function (err, data) {
  1309. assert.ok(!err, 'putBucketAcl 成功');
  1310. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1311. assert.ok(data.ACL === 'public-read-write');
  1312. done();
  1313. });
  1314. });
  1315. });
  1316. test('putBucketAcl() header GrantRead:1001,1002', function (done, assert) {
  1317. var GrantRead = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
  1318. cos.putBucketAcl({
  1319. Bucket: config.Bucket,
  1320. Region: config.Region,
  1321. GrantRead: GrantRead,
  1322. }, function (err, data) {
  1323. assert.ok(!err, 'putBucketAcl 成功');
  1324. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1325. assert.ok(data.GrantRead = GrantRead);
  1326. done();
  1327. });
  1328. });
  1329. });
  1330. test('putBucketAcl() header GrantWrite:1001,1002', function (done, assert) {
  1331. var GrantWrite = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
  1332. cos.putBucketAcl({
  1333. Bucket: config.Bucket,
  1334. Region: config.Region,
  1335. GrantWrite: GrantWrite,
  1336. }, function (err, data) {
  1337. assert.ok(!err, 'putBucketAcl 成功');
  1338. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1339. assert.ok(data.GrantWrite = GrantWrite);
  1340. done();
  1341. });
  1342. });
  1343. });
  1344. test('putBucketAcl() header GrantFullControl:1001,1002', function (done, assert) {
  1345. var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
  1346. cos.putBucketAcl({
  1347. Bucket: config.Bucket,
  1348. Region: config.Region,
  1349. GrantFullControl: GrantFullControl,
  1350. }, function (err, data) {
  1351. assert.ok(!err, 'putBucketAcl 成功');
  1352. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1353. assert.ok(data.GrantFullControl = GrantFullControl);
  1354. done();
  1355. });
  1356. });
  1357. });
  1358. test('putBucketAcl() header ACL:public-read, GrantFullControl:1001,1002', function (done, assert) {
  1359. var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
  1360. cos.putBucketAcl({
  1361. Bucket: config.Bucket,
  1362. Region: config.Region,
  1363. GrantFullControl: GrantFullControl,
  1364. ACL: 'public-read',
  1365. }, function (err, data) {
  1366. assert.ok(!err, 'putBucketAcl 成功');
  1367. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1368. assert.ok(data.GrantFullControl = GrantFullControl);
  1369. assert.ok(data.ACL === 'public-read');
  1370. done();
  1371. });
  1372. });
  1373. });
  1374. test('putBucketAcl() xml', function (done, assert) {
  1375. cos.putBucketAcl({
  1376. Bucket: config.Bucket,
  1377. Region: config.Region,
  1378. AccessControlPolicy: AccessControlPolicy
  1379. }, function (err, data) {
  1380. assert.ok(!err, 'putBucketAcl 成功');
  1381. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1382. assert.ok(data.Grants.length === 1);
  1383. assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002', '设置 AccessControlPolicy ID 正确');
  1384. assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', '设置 AccessControlPolicy Permission 正确');
  1385. done();
  1386. });
  1387. });
  1388. });
  1389. test('putBucketAcl() xml2', function (done, assert) {
  1390. cos.putBucketAcl({
  1391. Bucket: config.Bucket,
  1392. Region: config.Region,
  1393. AccessControlPolicy: AccessControlPolicy2,
  1394. }, function (err, data) {
  1395. assert.ok(!err, 'putBucketAcl 成功');
  1396. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) {
  1397. assert.ok(data.Grants.length === 1);
  1398. assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002');
  1399. assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ');
  1400. done();
  1401. });
  1402. });
  1403. });
  1404. test('putBucketAcl() decodeAcl', function (done, assert) {
  1405. cos.getBucketAcl({
  1406. Bucket: config.Bucket,
  1407. Region: config.Region
  1408. }, function (err, data) {
  1409. cos.putBucketAcl({
  1410. Bucket: config.Bucket,
  1411. Region: config.Region,
  1412. GrantFullControl: data.GrantFullControl,
  1413. GrantWrite: data.GrantWrite,
  1414. GrantRead: data.GrantRead,
  1415. ACL: data.ACL,
  1416. }, function (err, data) {
  1417. assert.ok(data);
  1418. done();
  1419. });
  1420. });
  1421. });
  1422. });
  1423. group('ObjectAcl', function () {
  1424. var AccessControlPolicy = {
  1425. "Owner": {
  1426. "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
  1427. },
  1428. "Grants": [{
  1429. "Grantee": {
  1430. "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
  1431. },
  1432. "Permission": "READ"
  1433. }]
  1434. };
  1435. var AccessControlPolicy2 = {
  1436. "Owner": {
  1437. "ID": 'qcs::cam::uin/10001:uin/10001' // 10001 是 QQ 号
  1438. },
  1439. "Grant": {
  1440. "Grantee": {
  1441. "ID": "qcs::cam::uin/10002:uin/10002", // 10002 是 QQ 号
  1442. },
  1443. "Permission": "READ"
  1444. }
  1445. };
  1446. test('putObjectAcl() header ACL:private', function (done, assert) {
  1447. cos.putObject({
  1448. Bucket: config.Bucket,
  1449. Region: config.Region,
  1450. Key: '1.txt',
  1451. Body: 'hello!',
  1452. }, function (err, data) {
  1453. assert.ok(!err);
  1454. cos.putObjectAcl({
  1455. Bucket: config.Bucket,
  1456. Region: config.Region,
  1457. ACL: 'private',
  1458. Key: '1.txt',
  1459. }, function (err, data) {
  1460. assert.ok(!err, 'putObjectAcl 成功');
  1461. cos.getObjectAcl({
  1462. Bucket: config.Bucket,
  1463. Region: config.Region,
  1464. Key: '1.txt'
  1465. }, function (err, data) {
  1466. assert.ok(data.ACL = 'private');
  1467. AccessControlPolicy.Owner.ID = data.Owner.ID;
  1468. AccessControlPolicy2.Owner.ID = data.Owner.ID;
  1469. assert.ok(data.Grants.length === 1);
  1470. done();
  1471. });
  1472. });
  1473. });
  1474. });
  1475. test('putObjectAcl() header ACL:default', function (done, assert) {
  1476. cos.putObjectAcl({
  1477. Bucket: config.Bucket,
  1478. Region: config.Region,
  1479. ACL: 'default',
  1480. Key: '1.txt',
  1481. }, function (err, data) {
  1482. assert.ok(!err, 'putObjectAcl 成功');
  1483. cos.getObjectAcl({
  1484. Bucket: config.Bucket,
  1485. Region: config.Region,
  1486. Key: '1.txt'
  1487. }, function (err, data) {
  1488. assert.ok(data.ACL = 'default');
  1489. done();
  1490. });
  1491. });
  1492. });
  1493. test('putObjectAcl() header ACL:public-read', function (done, assert) {
  1494. cos.putObjectAcl({
  1495. Bucket: config.Bucket,
  1496. Region: config.Region,
  1497. ACL: 'public-read',
  1498. Key: '1.txt',
  1499. }, function (err, data) {
  1500. assert.ok(!err, 'putObjectAcl 成功');
  1501. cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) {
  1502. assert.ok(data.ACL = 'public-read');
  1503. done();
  1504. });
  1505. });
  1506. });
  1507. // Object 不再支持修改写权限
  1508. // test('putObjectAcl() header ACL:public-read-write', function (done, assert) {
  1509. // cos.putObjectAcl({
  1510. // Bucket: config.Bucket,
  1511. // Region: config.Region,
  1512. // ACL: 'public-read-write',
  1513. // Key: '1.txt',
  1514. // }, function (err, data) {
  1515. // assert.ok(!err, 'putObjectAcl 成功');
  1516. // cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) {
  1517. // assert.ok(data.ACL = 'public-read-write');
  1518. // done();
  1519. // });
  1520. // });
  1521. // });
  1522. test('putObjectAcl() header GrantRead:1001,1002', function (done, assert) {
  1523. var GrantRead = 'id="qcs::cam::uin/1001:uin/1001",id="qcs::cam::uin/1002:uin/1002"';
  1524. cos.putObjectAcl({
  1525. Bucket: config.Bucket,
  1526. Region: config.Region,
  1527. GrantRead: GrantRead,
  1528. Key: '1.txt',
  1529. }, function (err, data) {
  1530. assert.ok(!err, 'putObjectAcl 成功');
  1531. cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) {
  1532. assert.ok(data.GrantRead = GrantRead);
  1533. done();
  1534. });
  1535. });
  1536. });
  1537. // Object 不再支持修改写权限
  1538. // test('putObjectAcl() header GrantWrite:1001,1002', function (done, assert) {
  1539. // var GrantWrite = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
  1540. // cos.putObjectAcl({
  1541. // Bucket: config.Bucket,
  1542. // Region: config.Region,
  1543. // GrantWrite: GrantWrite,
  1544. // Key: '1.txt',
  1545. // }, function (err, data) {
  1546. // assert.ok(!err, 'putObjectAcl 成功');
  1547. // cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) {
  1548. // assert.ok(data.GrantWrite = GrantWrite);
  1549. // done();
  1550. // });
  1551. // });
  1552. // });
  1553. test('putObjectAcl() header GrantFullControl:1001,1002', function (done, assert) {
  1554. var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
  1555. cos.putObjectAcl({
  1556. Bucket: config.Bucket,
  1557. Region: config.Region,
  1558. GrantFullControl: GrantFullControl,
  1559. Key: '1.txt',
  1560. }, function (err, data) {
  1561. assert.ok(!err, 'putObjectAcl 成功');
  1562. cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) {
  1563. assert.ok(data.GrantFullControl = GrantFullControl);
  1564. done();
  1565. });
  1566. });
  1567. });
  1568. test('putObjectAcl() header ACL:public-read, GrantRead:1001,1002', function (done, assert) {
  1569. var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"';
  1570. cos.putObjectAcl({
  1571. Bucket: config.Bucket,
  1572. Region: config.Region,
  1573. GrantFullControl: GrantFullControl,
  1574. ACL: 'public-read',
  1575. Key: '1.txt',
  1576. }, function (err, data) {
  1577. assert.ok(!err, 'putObjectAcl 成功');
  1578. cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) {
  1579. assert.ok(data.GrantFullControl = GrantFullControl);
  1580. assert.ok(data.ACL = 'public-read');
  1581. done();
  1582. });
  1583. });
  1584. });
  1585. test('putObjectAcl() xml', function (done, assert) {
  1586. cos.putObjectAcl({
  1587. Bucket: config.Bucket,
  1588. Region: config.Region,
  1589. AccessControlPolicy: AccessControlPolicy,
  1590. Key: '1.txt',
  1591. }, function (err, data) {
  1592. assert.ok(!err, 'putObjectAcl 成功');
  1593. cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) {
  1594. assert.ok(data.Grants.length === 1);
  1595. assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002', '设置 AccessControlPolicy ID 正确');
  1596. assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', '设置 AccessControlPolicy Permission 正确');
  1597. done();
  1598. });
  1599. });
  1600. });
  1601. test('putObjectAcl() xml2', function (done, assert) {
  1602. cos.putObjectAcl({
  1603. Bucket: config.Bucket,
  1604. Region: config.Region,
  1605. AccessControlPolicy: AccessControlPolicy2,
  1606. Key: '1.txt',
  1607. }, function (err, data) {
  1608. assert.ok(!err, 'putObjectAcl 成功');
  1609. cos.getObjectAcl({
  1610. Bucket: config.Bucket,
  1611. Region: config.Region,
  1612. Key: '1.txt'
  1613. }, function (err, data) {
  1614. assert.ok(data.Grants.length === 1);
  1615. assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/10002:uin/10002', 'ID 正确');
  1616. assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', 'Permission 正确');
  1617. done();
  1618. });
  1619. });
  1620. });
  1621. test('putObjectAcl() decodeAcl', function (done, assert) {
  1622. cos.getObjectAcl({
  1623. Bucket: config.Bucket,
  1624. Region: config.Region,
  1625. Key: '1.txt'
  1626. }, function (err, data) {
  1627. cos.putObjectAcl({
  1628. Bucket: config.Bucket,
  1629. Region: config.Region,
  1630. Key: '1.txt',
  1631. GrantFullControl: data.GrantFullControl,
  1632. GrantWrite: data.GrantWrite,
  1633. GrantRead: data.GrantRead,
  1634. ACL: data.ACL,
  1635. }, function (err, data) {
  1636. assert.ok(data);
  1637. done();
  1638. });
  1639. });
  1640. });
  1641. });
  1642. group('BucketCors', function () {
  1643. var CORSRules = [{
  1644. "AllowedOrigins": ["*"],
  1645. "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"],
  1646. "AllowedHeaders": ["*", 'test-' + Date.now().toString(36)],
  1647. "ExposeHeaders": [
  1648. 'etag',
  1649. 'date',
  1650. 'content-length',
  1651. 'expires',
  1652. 'cache-control',
  1653. 'content-disposition',
  1654. 'content-encoding',
  1655. 'x-cos-acl',
  1656. 'x-cos-version-id',
  1657. 'x-cos-request-id',
  1658. 'x-cos-delete-marker',
  1659. 'x-cos-server-side-encryption',
  1660. 'x-cos-storage-class',
  1661. 'x-cos-acl',
  1662. 'x-cos-meta-test',
  1663. 'x-cos-tagging-count',
  1664. ],
  1665. "MaxAgeSeconds": "5"
  1666. }];
  1667. var CORSRulesMulti = [{
  1668. "AllowedOrigins": ["*"],
  1669. "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"],
  1670. "AllowedHeaders": ["*"],
  1671. "ExposeHeaders": ["ETag", "Date", "Content-Length", "x-cos-acl", "x-cos-version-id", "x-cos-request-id", "x-cos-delete-marker", "x-cos-server-side-encryption"],
  1672. "MaxAgeSeconds": "5"
  1673. }, {
  1674. "AllowedOrigins": ["http://qq.com", "http://qcloud.com"],
  1675. "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"],
  1676. "AllowedHeaders": ["*"],
  1677. "ExposeHeaders": ["ETag", "Date", "Content-Length", "x-cos-acl", "x-cos-version-id", "x-cos-request-id", "x-cos-delete-marker", "x-cos-server-side-encryption"],
  1678. "MaxAgeSeconds": "5"
  1679. }];
  1680. test('putBucketCors() old CORSConfiguration', function (done, assert) {
  1681. CORSRules[0].AllowedHeaders[1] = 'test-' + Date.now().toString(36);
  1682. cos.putBucketCors({
  1683. Bucket: config.Bucket,
  1684. Region: config.Region,
  1685. CORSConfiguration: {
  1686. CORSRules: CORSRules
  1687. }
  1688. }, function (err, data) {
  1689. assert.ok(!err);
  1690. setTimeout(function () {
  1691. cos.getBucketCors({
  1692. Bucket: config.Bucket,
  1693. Region: config.Region
  1694. }, function (err, data) {
  1695. assert.ok(comparePlainObject(CORSRules, data.CORSRules));
  1696. done();
  1697. });
  1698. }, 2000);
  1699. });
  1700. });
  1701. test('putBucketCors() multi', function (done, assert) {
  1702. cos.putBucketCors({
  1703. Bucket: config.Bucket,
  1704. Region: config.Region,
  1705. CORSConfiguration: {
  1706. CORSRules: CORSRulesMulti
  1707. }
  1708. }, function (err, data) {
  1709. assert.ok(!err);
  1710. setTimeout(function () {
  1711. cos.getBucketCors({
  1712. Bucket: config.Bucket,
  1713. Region: config.Region
  1714. }, function (err, data) {
  1715. assert.ok(comparePlainObject(CORSRulesMulti, data.CORSRules));
  1716. done();
  1717. });
  1718. }, 2000);
  1719. });
  1720. });
  1721. test('putBucketCors() old CORSRules', function (done, assert) {
  1722. CORSRules[0].AllowedHeaders[1] = 'test-' + Date.now().toString(36);
  1723. cos.putBucketCors({
  1724. Bucket: config.Bucket,
  1725. Region: config.Region,
  1726. CORSRules: CORSRules
  1727. }, function (err, data) {
  1728. assert.ok(!err);
  1729. setTimeout(function () {
  1730. cos.getBucketCors({
  1731. Bucket: config.Bucket,
  1732. Region: config.Region
  1733. }, function (err, data) {
  1734. assert.ok(comparePlainObject(CORSRules, data.CORSRules));
  1735. done();
  1736. });
  1737. }, 2000);
  1738. });
  1739. });
  1740. test('putBucketCors(),getBucketCors()', function (done, assert) {
  1741. CORSRules[0].AllowedHeaders = ['*'];
  1742. cos.putBucketCors({
  1743. Bucket: config.Bucket,
  1744. Region: config.Region,
  1745. CORSConfiguration: {
  1746. CORSRules: CORSRules
  1747. }
  1748. }, function (err, data) {
  1749. assert.ok(!err);
  1750. setTimeout(function () {
  1751. cos.getBucketCors({
  1752. Bucket: config.Bucket,
  1753. Region: config.Region
  1754. }, function (err, data) {
  1755. assert.ok(comparePlainObject(CORSRules, data.CORSRules));
  1756. done();
  1757. });
  1758. }, 2000);
  1759. });
  1760. });
  1761. });
  1762. group('BucketTagging', function () {
  1763. var Tags = [
  1764. {Key: "k1", Value: "v1"}
  1765. ];
  1766. var TagsMulti = [
  1767. {Key: "k1", Value: "v1"},
  1768. {Key: "k2", Value: "v2"},
  1769. ];
  1770. test('putBucketTagging(),getBucketTagging()', function (done, assert) {
  1771. Tags[0].Value = Date.now().toString(36);
  1772. cos.putBucketTagging({
  1773. Bucket: config.Bucket,
  1774. Region: config.Region,
  1775. Tagging: {
  1776. Tags: Tags
  1777. }
  1778. }, function (err, data) {
  1779. assert.ok(!err);
  1780. setTimeout(function () {
  1781. cos.getBucketTagging({
  1782. Bucket: config.Bucket,
  1783. Region: config.Region
  1784. }, function (err, data) {
  1785. assert.ok(comparePlainObject(Tags, data.Tags));
  1786. done();
  1787. });
  1788. }, 1000);
  1789. });
  1790. });
  1791. test('deleteBucketTagging()', function (done, assert) {
  1792. cos.deleteBucketTagging({
  1793. Bucket: config.Bucket,
  1794. Region: config.Region
  1795. }, function (err, data) {
  1796. assert.ok(!err);
  1797. setTimeout(function () {
  1798. cos.getBucketTagging({
  1799. Bucket: config.Bucket,
  1800. Region: config.Region
  1801. }, function (err, data) {
  1802. assert.ok(comparePlainObject([], data.Tags));
  1803. done();
  1804. });
  1805. }, 1000);
  1806. });
  1807. });
  1808. test('putBucketTagging() multi', function (done, assert) {
  1809. Tags[0].Value = Date.now().toString(36);
  1810. cos.putBucketTagging({
  1811. Bucket: config.Bucket,
  1812. Region: config.Region,
  1813. Tagging: {
  1814. Tags: TagsMulti
  1815. }
  1816. }, function (err, data) {
  1817. assert.ok(!err);
  1818. setTimeout(function () {
  1819. cos.getBucketTagging({
  1820. Bucket: config.Bucket,
  1821. Region: config.Region
  1822. }, function (err, data) {
  1823. assert.ok(comparePlainObject(TagsMulti, data.Tags));
  1824. done();
  1825. });
  1826. }, 1000);
  1827. });
  1828. });
  1829. });
  1830. group('BucketPolicy', function () {
  1831. var Prefix = Date.now().toString(36);
  1832. var Policy = {
  1833. "version": "2.0",
  1834. "principal": {"qcs": ["qcs::cam::uin/10001:uin/10001"]}, // 这里的 10001 是 QQ 号
  1835. "statement": [{
  1836. "effect": "allow",
  1837. "action": [
  1838. "name/cos:GetBucket",
  1839. "name/cos:PutObject",
  1840. "name/cos:PostObject",
  1841. "name/cos:PutObjectCopy",
  1842. "name/cos:InitiateMultipartUpload",
  1843. "name/cos:UploadPart",
  1844. "name/cos:UploadPartCopy",
  1845. "name/cos:CompleteMultipartUpload",
  1846. "name/cos:AbortMultipartUpload",
  1847. "name/cos:AppendObject"
  1848. ],
  1849. "resource": ["qcs::cos:" + config.Region + ":uid/" + AppId + ":" + BucketLongName + "//" + AppId + "/" + BucketShortName + "/" + Prefix + "/*"] // 1250000000 是 appid
  1850. }]
  1851. };
  1852. var getRes = function (s) {
  1853. var t = s && s[0];
  1854. var res = t && t.resource && t.resource[0];
  1855. return res;
  1856. };
  1857. test('putBucketPolicy(),getBucketPolicy()', function (done, assert) {
  1858. cos.putBucketPolicy({
  1859. Bucket: config.Bucket,
  1860. Region: config.Region,
  1861. Policy: Policy
  1862. }, function (err, data) {
  1863. assert.ok(!err);
  1864. cos.getBucketPolicy({
  1865. Bucket: config.Bucket,
  1866. Region: config.Region
  1867. }, function (err, data) {
  1868. assert.ok(getRes(Policy.statement) === getRes(data.Policy.Statement));
  1869. done();
  1870. });
  1871. });
  1872. });
  1873. test('putBucketPolicy() s3', function (done, assert) {
  1874. cos.putBucketPolicy({
  1875. Bucket: config.Bucket,
  1876. Region: config.Region,
  1877. Policy: JSON.stringify(Policy)
  1878. }, function (err, data) {
  1879. assert.ok(!err);
  1880. cos.getBucketPolicy({
  1881. Bucket: config.Bucket,
  1882. Region: config.Region
  1883. }, function (err, data) {
  1884. assert.ok(getRes(Policy.statement) === getRes(data.Policy.Statement));
  1885. done();
  1886. });
  1887. });
  1888. });
  1889. test('deleteBucketPolicy()', function (done, assert) {
  1890. cos.deleteBucketPolicy({
  1891. Bucket: config.Bucket,
  1892. Region: config.Region,
  1893. Policy: JSON.stringify(Policy)
  1894. }, function (err, data) {
  1895. assert.ok(!err);
  1896. cos.getBucketPolicy({
  1897. Bucket: config.Bucket,
  1898. Region: config.Region
  1899. }, function (err, data) {
  1900. assert.ok(err.ErrorStatus === 'Policy Not Found');
  1901. done();
  1902. });
  1903. });
  1904. });
  1905. });
  1906. group('BucketLocation', function () {
  1907. test('getBucketLocation()', function (done, assert) {
  1908. cos.getBucketLocation({
  1909. Bucket: config.Bucket,
  1910. Region: config.Region
  1911. }, function (err, data) {
  1912. var map1 = {
  1913. 'tianjin': 'ap-beijing-1',
  1914. 'cn-south-2': 'ap-guangzhou-2',
  1915. 'cn-south': 'ap-guangzhou',
  1916. 'cn-east': 'ap-shanghai',
  1917. 'cn-southwest': 'ap-chengdu',
  1918. };
  1919. var map2 = {
  1920. 'ap-beijing-1': 'tianjin',
  1921. 'ap-guangzhou-2': 'cn-south-2',
  1922. 'ap-guangzhou': 'cn-south',
  1923. 'ap-shanghai': 'cn-east',
  1924. 'ap-chengdu': 'cn-southwest',
  1925. };
  1926. assert.ok(data.LocationConstraint === config.Region || data.LocationConstraint === map1[config.Region] ||
  1927. data.LocationConstraint === map2[config.Region]);
  1928. done();
  1929. });
  1930. });
  1931. });
  1932. group('BucketLifecycle', function () {
  1933. var Rules = [{
  1934. 'ID': '1',
  1935. 'Filter': {
  1936. 'Prefix': 'test_' + Date.now().toString(36),
  1937. },
  1938. 'Status': 'Enabled',
  1939. 'Transition': {
  1940. 'Date': '2018-07-29T16:00:00.000Z',
  1941. 'StorageClass': 'STANDARD_IA'
  1942. }
  1943. }];
  1944. var RulesMulti = [{
  1945. 'ID': '1',
  1946. 'Filter': {
  1947. 'Prefix': 'test1_' + Date.now().toString(36),
  1948. },
  1949. 'Status': 'Enabled',
  1950. 'Transition': {
  1951. 'Date': '2018-07-29T16:00:00.000Z',
  1952. 'StorageClass': 'STANDARD_IA'
  1953. }
  1954. }, {
  1955. 'ID': '2',
  1956. 'Filter': {
  1957. 'Prefix': 'test2_' + Date.now().toString(36),
  1958. },
  1959. 'Status': 'Enabled',
  1960. 'Transition': {
  1961. 'Date': '2018-07-29T16:00:00.000Z',
  1962. 'StorageClass': 'STANDARD_IA'
  1963. }
  1964. }];
  1965. test('deleteBucketLifecycle()', function (done, assert) {
  1966. cos.deleteBucketLifecycle({
  1967. Bucket: config.Bucket,
  1968. Region: config.Region
  1969. }, function (err, data) {
  1970. assert.ok(!err);
  1971. setTimeout(function () {
  1972. cos.getBucketLifecycle({
  1973. Bucket: config.Bucket,
  1974. Region: config.Region
  1975. }, function (err, data) {
  1976. assert.ok(comparePlainObject([], data.Rules));
  1977. done();
  1978. });
  1979. }, 2000);
  1980. });
  1981. });
  1982. test('putBucketLifecycle(),getBucketLifecycle()', function (done, assert) {
  1983. Rules[0].Filter.Prefix = 'test_' + Date.now().toString(36);
  1984. cos.putBucketLifecycle({
  1985. Bucket: config.Bucket,
  1986. Region: config.Region,
  1987. LifecycleConfiguration: {
  1988. Rules: Rules
  1989. }
  1990. }, function (err, data) {
  1991. assert.ok(!err);
  1992. setTimeout(function () {
  1993. cos.getBucketLifecycle({
  1994. Bucket: config.Bucket,
  1995. Region: config.Region
  1996. }, function (err, data) {
  1997. assert.ok(comparePlainObject(Rules, data && data.Rules));
  1998. done();
  1999. });
  2000. }, 2000);
  2001. });
  2002. });
  2003. test('putBucketLifecycle() multi', function (done, assert) {
  2004. Rules[0].Filter.Prefix = 'test_' + Date.now().toString(36);
  2005. cos.putBucketLifecycle({
  2006. Bucket: config.Bucket,
  2007. Region: config.Region,
  2008. LifecycleConfiguration: {
  2009. Rules: RulesMulti
  2010. }
  2011. }, function (err, data) {
  2012. assert.ok(!err);
  2013. setTimeout(function () {
  2014. cos.getBucketLifecycle({
  2015. Bucket: config.Bucket,
  2016. Region: config.Region
  2017. }, function (err, data) {
  2018. assert.ok(comparePlainObject(RulesMulti, data.Rules));
  2019. done();
  2020. });
  2021. }, 2000);
  2022. });
  2023. });
  2024. });
  2025. group('BucketWebsite', function () {
  2026. var RoutingRules = [{
  2027. Condition: {
  2028. HttpErrorCodeReturnedEquals: "404"
  2029. },
  2030. Redirect: {
  2031. Protocol: "https",
  2032. ReplaceKeyWith: "404.html"
  2033. }
  2034. }, {
  2035. Condition: {
  2036. KeyPrefixEquals: "docs/"
  2037. },
  2038. Redirect: {
  2039. Protocol: "https",
  2040. ReplaceKeyPrefixWith: "documents/"
  2041. }
  2042. }, {
  2043. Condition: {
  2044. KeyPrefixEquals: "img/"
  2045. },
  2046. Redirect: {
  2047. Protocol: "https",
  2048. ReplaceKeyWith: "picture.jpg"
  2049. }
  2050. }];
  2051. var WebsiteConfiguration = {
  2052. IndexDocument: {
  2053. Suffix: "index.html"
  2054. },
  2055. RedirectAllRequestsTo: {
  2056. Protocol: "https"
  2057. },
  2058. ErrorDocument: {
  2059. Key: "error.html"
  2060. },
  2061. };
  2062. test('putBucketWebsite(),getBucketWebsite()', function (done, assert) {
  2063. cos.putBucketWebsite({
  2064. Bucket: config.Bucket,
  2065. Region: config.Region,
  2066. WebsiteConfiguration: WebsiteConfiguration
  2067. }, function (err, data) {
  2068. assert.ok(!err);
  2069. setTimeout(function () {
  2070. cos.getBucketWebsite({
  2071. Bucket: config.Bucket,
  2072. Region: config.Region
  2073. }, function (err, data) {
  2074. assert.ok(comparePlainObject(WebsiteConfiguration, data.WebsiteConfiguration));
  2075. done();
  2076. });
  2077. }, 2000);
  2078. });
  2079. });
  2080. test('putBucketWebsite() multi RoutingRules', function (done, assert) {
  2081. WebsiteConfiguration.RoutingRules = RoutingRules;
  2082. cos.putBucketWebsite({
  2083. Bucket: config.Bucket,
  2084. Region: config.Region,
  2085. WebsiteConfiguration: WebsiteConfiguration
  2086. }, function (err, data) {
  2087. assert.ok(!err);
  2088. setTimeout(function () {
  2089. cos.getBucketWebsite({
  2090. Bucket: config.Bucket,
  2091. Region: config.Region
  2092. }, function (err, data) {
  2093. assert.ok(comparePlainObject(WebsiteConfiguration, data.WebsiteConfiguration));
  2094. done();
  2095. });
  2096. }, 2000);
  2097. });
  2098. });
  2099. test('deleteBucketWebsite()', function (done, assert) {
  2100. cos.deleteBucketWebsite({
  2101. Bucket: config.Bucket,
  2102. Region: config.Region
  2103. }, function (err, data) {
  2104. assert.ok(!err);
  2105. setTimeout(function () {
  2106. cos.getBucketWebsite({
  2107. Bucket: config.Bucket,
  2108. Region: config.Region
  2109. }, function (err, data) {
  2110. assert.ok(comparePlainObject({}, data.WebsiteConfiguration));
  2111. done();
  2112. });
  2113. }, 2000);
  2114. });
  2115. });
  2116. });
  2117. group('BucketDomain', function () {
  2118. var DomainRule = [{
  2119. Status: "DISABLED",
  2120. Name: "www.testDomain1.com",
  2121. Type: "REST"
  2122. },
  2123. {
  2124. Status: "DISABLED",
  2125. Name: "www.testDomain2.com",
  2126. Type: "WEBSITE"
  2127. }];
  2128. test('putBucketDomain(),getBucketDomain()', function (done, assert) {
  2129. cos.putBucketDomain({
  2130. Bucket: config.Bucket,
  2131. Region: config.Region,
  2132. DomainRule: DomainRule
  2133. }, function (err, data) {
  2134. assert.ok(!err);
  2135. setTimeout(function () {
  2136. cos.getBucketDomain({
  2137. Bucket: config.Bucket,
  2138. Region: config.Region
  2139. }, function (err, data) {
  2140. assert.ok(comparePlainObject(DomainRule, data.DomainRule));
  2141. done();
  2142. });
  2143. }, 2000);
  2144. });
  2145. });
  2146. // test('putBucketDomain() multi', function (done, assert) {
  2147. // cos.putBucketDomain({
  2148. // Bucket: config.Bucket,
  2149. // Region: config.Region,
  2150. // DomainRule: DomainRuleMulti
  2151. // }, function (err, data) {
  2152. // assert.ok(!err);
  2153. // setTimeout(function () {
  2154. // cos.getBucketDomain({
  2155. // Bucket: config.Bucket,
  2156. // Region: config.Region
  2157. // }, function (err, data) {
  2158. // assert.ok(comparePlainObject(DomainRuleMulti, data.DomainRule));
  2159. // done();
  2160. // });
  2161. // }, 2000);
  2162. // });
  2163. // });
  2164. test('deleteBucketDomain()', function (done, assert) {
  2165. cos.deleteBucketDomain({
  2166. Bucket: config.Bucket,
  2167. Region: config.Region
  2168. }, function (err, data) {
  2169. assert.ok(!err);
  2170. setTimeout(function () {
  2171. cos.getBucketDomain({
  2172. Bucket: config.Bucket,
  2173. Region: config.Region
  2174. }, function (err, data) {
  2175. assert.ok(comparePlainObject([], data.DomainRule));
  2176. done();
  2177. });
  2178. }, 2000);
  2179. });
  2180. });
  2181. });
  2182. group('params check Region', function () {
  2183. test('params check', function (done, assert) {
  2184. cos.headBucket({
  2185. Bucket: config.Bucket,
  2186. Region: 'cos.ap-guangzhou'
  2187. }, function (err, data) {
  2188. assert.ok(err.message === 'param Region should not be start with "cos."');
  2189. done();
  2190. });
  2191. });
  2192. test('params check Region', function (done, assert) {
  2193. cos.headBucket({
  2194. Bucket: config.Bucket,
  2195. Region: 'gz'
  2196. }, function (err, data) {
  2197. assert.ok(err);
  2198. done();
  2199. });
  2200. });
  2201. });
  2202. group('Key 特殊字符处理', function () {
  2203. test('Key 特殊字符处理', function (done, assert) {
  2204. var Key = '中文→↓←→↖↗↙↘! $&\'()+,-.0123456789=@ABCDEFGHIJKLMNOPQRSTUV?WXYZ[]^_`abcdefghijklmnopqrstuvwxyz{}~.jpg';
  2205. cos.putObject({
  2206. Bucket: config.Bucket,
  2207. Region: config.Region,
  2208. Key: Key,
  2209. Body: 'hello',
  2210. }, function (err, data) {
  2211. assert.ok(!err);
  2212. cos.deleteObject({
  2213. Bucket: config.Bucket,
  2214. Region: config.Region,
  2215. Key: Key,
  2216. Body: 'hello',
  2217. }, function (err, data) {
  2218. assert.ok(!err);
  2219. cos.deleteMultipleObject({
  2220. Bucket: config.Bucket,
  2221. Region: config.Region,
  2222. Objects: {
  2223. Key: Key,
  2224. },
  2225. }, function (err, data) {
  2226. assert.ok(!err);
  2227. done();
  2228. });
  2229. });
  2230. });
  2231. });
  2232. });
  2233. group('Bucket 格式有误', function () {
  2234. test('Bucket 带有中文', function (done, assert) {
  2235. cos.headBucket({
  2236. Bucket: '中文-1250000000',
  2237. Region: config.Region,
  2238. }, function (err, data) {
  2239. assert.ok(err && err.message === 'Bucket should format as "test-1250000000".');
  2240. done();
  2241. });
  2242. });
  2243. test('Bucket 带有 /', function (done, assert) {
  2244. cos.headBucket({
  2245. Bucket: 'te/st-1250000000',
  2246. Region: config.Region,
  2247. }, function (err, data) {
  2248. assert.ok(err && err.message === 'Bucket should format as "test-1250000000".');
  2249. done();
  2250. });
  2251. });
  2252. test('Bucket 带有 .', function (done, assert) {
  2253. cos.headBucket({
  2254. Bucket: 'te.st-1250000000',
  2255. Region: config.Region,
  2256. }, function (err, data) {
  2257. assert.ok(err && err.message === 'Bucket should format as "test-1250000000".');
  2258. done();
  2259. });
  2260. });
  2261. test('Bucket 带有 :', function (done, assert) {
  2262. cos.headBucket({
  2263. Bucket: 'te:st-1250000000',
  2264. Region: config.Region,
  2265. }, function (err, data) {
  2266. assert.ok(err && err.message === 'Bucket should format as "test-1250000000".');
  2267. done();
  2268. });
  2269. });
  2270. });
  2271. group('Region 格式有误', function () {
  2272. test('Region 带有中文', function (done, assert) {
  2273. cos.headBucket({
  2274. Bucket: 'test-1250000000',
  2275. Region: '中文',
  2276. }, function (err, data) {
  2277. assert.ok(err && err.message === 'Region format error.');
  2278. done();
  2279. });
  2280. });
  2281. test('Region 带有 /', function (done, assert) {
  2282. cos.headBucket({
  2283. Bucket: 'test-1250000000',
  2284. Region: 'test/',
  2285. }, function (err, data) {
  2286. assert.ok(err && err.message === 'Region format error.');
  2287. done();
  2288. });
  2289. });
  2290. test('Region 带有 :', function (done, assert) {
  2291. cos.headBucket({
  2292. Bucket: 'test-1250000000',
  2293. Region: 'test:',
  2294. }, function (err, data) {
  2295. assert.ok(err && err.message === 'Region format error.');
  2296. done();
  2297. });
  2298. });
  2299. });
  2300. group('复制文件', function () {
  2301. test('sliceCopyFile() 正常分片复制', function (done, assert) {
  2302. var filename = '10m.zip';
  2303. var Key = '10mb.copy.zip';
  2304. var blob = util.createFile({size: 1024 * 1024 * 10});
  2305. var lastPercent;
  2306. cos.putObject({
  2307. Bucket: config.Bucket,
  2308. Region: config.Region,
  2309. Key: filename,
  2310. Body: blob,
  2311. }, function (err, data) {
  2312. cos.sliceCopyFile({
  2313. Bucket: config.Bucket,
  2314. Region: config.Region,
  2315. Key: Key,
  2316. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/' + filename,
  2317. SliceSize: 5 * 1024 * 1024,
  2318. onProgress: function (info) {
  2319. lastPercent = info.percent;
  2320. }
  2321. }, function (err, data) {
  2322. assert.ok(data && data.ETag, '成功进行分片复制');
  2323. done();
  2324. });
  2325. });
  2326. });
  2327. test('sliceCopyFile() 单片复制', function (done, assert) {
  2328. var filename = '10m.zip';
  2329. var Key = '10mb.copy.zip';
  2330. cos.sliceCopyFile({
  2331. Bucket: config.Bucket,
  2332. Region: config.Region,
  2333. Key: Key,
  2334. CopySource: config.Bucket + '.cos.' + config.Region + '.myqcloud.com/' + filename,
  2335. SliceSize: 10 * 1024 * 1024,
  2336. }, function (err, data) {
  2337. if (err) throw err;
  2338. assert.ok(data && data.ETag, '成功进行单片复制');
  2339. done();
  2340. });
  2341. });
  2342. });
  2343. group('putObject 中文 Content-MD5', function () {
  2344. var fileBlob = dataURItoUploadBody('data:text/plain;base64,5Lit5paH');
  2345. // 这里两个用户正式测试的时候需要给 putObject 计算并加上 Content-MD5 字段
  2346. test('putObject 中文文件内容 带 Content-MD5', function (done, assert) {
  2347. var Key = '中文.txt';
  2348. cos.putObject({
  2349. Bucket: config.Bucket,
  2350. Region: config.Region,
  2351. Key: Key,
  2352. Body: fileBlob,
  2353. }, function (err, data) {
  2354. assert.ok(data && data.ETag, '成功进行上传');
  2355. done();
  2356. });
  2357. });
  2358. test('putObject 中文字符串 带 Content-MD5', function (done, assert) {
  2359. var Key = '中文.txt';
  2360. cos.putObject({
  2361. Bucket: config.Bucket,
  2362. Region: config.Region,
  2363. Key: Key,
  2364. Body: '中文',
  2365. }, function (err, data) {
  2366. assert.ok(data && data.ETag, '成功进行上传');
  2367. done();
  2368. });
  2369. });
  2370. });
  2371. group('deleteMultipleObject Key 带中文字符', function () {
  2372. test('deleteMultipleObject Key 带中文字符', function (done, assert) {
  2373. cos.deleteMultipleObject({
  2374. Bucket: config.Bucket,
  2375. Region: config.Region,
  2376. Objects: [
  2377. {Key: '中文/中文.txt'},
  2378. {Key: '中文/中文.zip', VersionId: 'MTg0NDY3NDI1MzM4NzM0ODA2MTI'},
  2379. {Key: unescape(encodeURIComponent('中文'))},
  2380. {Key: unescape('%e8%af%b4%2e%70%72%70%72')},
  2381. ]
  2382. }, function (err, data) {
  2383. assert.ok(!err, '成功进行批量删除');
  2384. done();
  2385. });
  2386. });
  2387. });
  2388. group('upload Content-Type', function () {
  2389. // putObject
  2390. test('putObject empty string Content-Type null -> text/plain', function (done, assert) {
  2391. cos.putObject({
  2392. Bucket: config.Bucket,
  2393. Region: config.Region,
  2394. Key: '1',
  2395. Body: '',
  2396. }, function (err, data) {
  2397. cos.headObject({
  2398. Bucket: config.Bucket,
  2399. Region: config.Region,
  2400. Key: '1',
  2401. }, function (err, data) {
  2402. assert.ok(data.headers['content-type'] === 'text/plain', 'Content-Type 正确');
  2403. done();
  2404. });
  2405. });
  2406. });
  2407. test('putObject string Content-Type null -> text/plain', function (done, assert) {
  2408. cos.putObject({
  2409. Bucket: config.Bucket,
  2410. Region: config.Region,
  2411. Key: '1.zip',
  2412. Body: '12345',
  2413. }, function (err, data) {
  2414. cos.headObject({
  2415. Bucket: config.Bucket,
  2416. Region: config.Region,
  2417. Key: '1.zip',
  2418. }, function (err, data) {
  2419. assert.ok(data.headers['content-type'] === 'text/plain', 'Content-Type 正确');
  2420. done();
  2421. });
  2422. });
  2423. });
  2424. test('putObject string Content-Type text/xml -> text/xml', function (done, assert) {
  2425. cos.putObject({
  2426. Bucket: config.Bucket,
  2427. Region: config.Region,
  2428. Key: '1.zip',
  2429. ContentType: 'text/xml',
  2430. Body: util.createFile({size: 1, type: 'text/html'}),
  2431. }, function (err, data) {
  2432. cos.headObject({
  2433. Bucket: config.Bucket,
  2434. Region: config.Region,
  2435. Key: '1.zip',
  2436. }, function (err, data) {
  2437. assert.ok(data.headers['content-type'] === 'text/xml', 'Content-Type 正确');
  2438. done();
  2439. });
  2440. });
  2441. });
  2442. test('putObject blob Content-Type text/xml -> text/xml', function (done, assert) {
  2443. cos.putObject({
  2444. Bucket: config.Bucket,
  2445. Region: config.Region,
  2446. Key: '1.zip',
  2447. ContentType: 'text/xml',
  2448. Body: util.createFile({size: 1, type: 'text/html'}),
  2449. }, function (err, data) {
  2450. cos.headObject({
  2451. Bucket: config.Bucket,
  2452. Region: config.Region,
  2453. Key: '1.zip',
  2454. }, function (err, data) {
  2455. assert.ok(data.headers['content-type'] === 'text/xml', 'Content-Type 正确');
  2456. done();
  2457. });
  2458. });
  2459. });
  2460. test('putObject blob Content-Type text/html -> text/html', function (done, assert) {
  2461. cos.putObject({
  2462. Bucket: config.Bucket,
  2463. Region: config.Region,
  2464. Key: '1.zip',
  2465. Body: util.createFile({size: 1, type: 'text/html'}),
  2466. }, function (err, data) {
  2467. cos.headObject({
  2468. Bucket: config.Bucket,
  2469. Region: config.Region,
  2470. Key: '1.zip',
  2471. }, function (err, data) {
  2472. assert.ok(data.headers['content-type'] === 'text/html', 'Content-Type 正确');
  2473. done();
  2474. });
  2475. });
  2476. });
  2477. test('putObject blob Content-Type null -> application/zip or application/octet-stream', function (done, assert) {
  2478. cos.putObject({
  2479. Bucket: config.Bucket,
  2480. Region: config.Region,
  2481. Key: '1.zip',
  2482. Body: util.createFile({size: 1}),
  2483. }, function (err, data) {
  2484. cos.headObject({
  2485. Bucket: config.Bucket,
  2486. Region: config.Region,
  2487. Key: '1.zip',
  2488. }, function (err, data) {
  2489. assert.ok(data.headers['content-type'] === 'application/zip', 'Content-Type 正确');
  2490. done();
  2491. });
  2492. });
  2493. });
  2494. test('putObject blob Content-Type null application/octet-stream', function (done, assert) {
  2495. cos.putObject({
  2496. Bucket: config.Bucket,
  2497. Region: config.Region,
  2498. Key: '1',
  2499. Body: util.createFile({size: 1}),
  2500. }, function (err, data) {
  2501. cos.headObject({
  2502. Bucket: config.Bucket,
  2503. Region: config.Region,
  2504. Key: '1',
  2505. }, function (err, data) {
  2506. assert.ok(data.headers['content-type'] === 'application/octet-stream', 'Content-Type 正确');
  2507. done();
  2508. });
  2509. });
  2510. });
  2511. test('putObject empty blob Content-Type null application/octet-stream', function (done, assert) {
  2512. cos.putObject({
  2513. Bucket: config.Bucket,
  2514. Region: config.Region,
  2515. Key: '1',
  2516. Body: util.createFile({size: 0}),
  2517. }, function (err, data) {
  2518. cos.headObject({
  2519. Bucket: config.Bucket,
  2520. Region: config.Region,
  2521. Key: '1',
  2522. }, function (err, data) {
  2523. assert.ok(data.headers['content-type'] === 'application/octet-stream', 'Content-Type 正确');
  2524. done();
  2525. });
  2526. });
  2527. });
  2528. // sliceUploadFile
  2529. test('sliceUploadFile string Content-Type null -> text/plain', function (done, assert) {
  2530. cos.sliceUploadFile({
  2531. Bucket: config.Bucket,
  2532. Region: config.Region,
  2533. Key: '1.zip',
  2534. Body: '12345',
  2535. }, function (err, data) {
  2536. cos.headObject({
  2537. Bucket: config.Bucket,
  2538. Region: config.Region,
  2539. Key: '1.zip',
  2540. }, function (err, data) {
  2541. assert.ok(data.headers['content-type'] === 'text/plain', 'Content-Type 正确');
  2542. done();
  2543. });
  2544. });
  2545. });
  2546. test('sliceUploadFile string Content-Type text/xml -> text/xml', function (done, assert) {
  2547. cos.sliceUploadFile({
  2548. Bucket: config.Bucket,
  2549. Region: config.Region,
  2550. Key: '1.zip',
  2551. ContentType: 'text/xml',
  2552. Body: util.createFile({size: 1, type: 'text/html'}),
  2553. }, function (err, data) {
  2554. cos.headObject({
  2555. Bucket: config.Bucket,
  2556. Region: config.Region,
  2557. Key: '1.zip',
  2558. }, function (err, data) {
  2559. assert.ok(data.headers['content-type'] === 'text/xml', 'Content-Type 正确');
  2560. done();
  2561. });
  2562. });
  2563. });
  2564. test('sliceUploadFile blob Content-Type text/xml -> text/xml', function (done, assert) {
  2565. cos.sliceUploadFile({
  2566. Bucket: config.Bucket,
  2567. Region: config.Region,
  2568. Key: '1.zip',
  2569. ContentType: 'text/xml',
  2570. Body: util.createFile({size: 1, type: 'text/html'}),
  2571. }, function (err, data) {
  2572. cos.headObject({
  2573. Bucket: config.Bucket,
  2574. Region: config.Region,
  2575. Key: '1.zip',
  2576. }, function (err, data) {
  2577. assert.ok(data.headers['content-type'] === 'text/xml', 'Content-Type 正确');
  2578. done();
  2579. });
  2580. });
  2581. });
  2582. test('sliceUploadFile blob Content-Type text/html -> text/html', function (done, assert) {
  2583. cos.sliceUploadFile({
  2584. Bucket: config.Bucket,
  2585. Region: config.Region,
  2586. Key: '1.zip',
  2587. Body: util.createFile({size: 1, type: 'text/html'}),
  2588. }, function (err, data) {
  2589. cos.headObject({
  2590. Bucket: config.Bucket,
  2591. Region: config.Region,
  2592. Key: '1.zip',
  2593. }, function (err, data) {
  2594. assert.ok(data.headers['content-type'] === 'text/html', 'Content-Type 正确');
  2595. done();
  2596. });
  2597. });
  2598. });
  2599. test('sliceUploadFile blob Content-Type null -> application/zip or application/octet-stream', function (done, assert) {
  2600. cos.sliceUploadFile({
  2601. Bucket: config.Bucket,
  2602. Region: config.Region,
  2603. Key: '1.zip',
  2604. Body: util.createFile({size: 1}),
  2605. }, function (err, data) {
  2606. cos.headObject({
  2607. Bucket: config.Bucket,
  2608. Region: config.Region,
  2609. Key: '1.zip',
  2610. }, function (err, data) {
  2611. var userAgent = navigator.userAgent || '';
  2612. var m = userAgent.match(/ TBS\/(\d{6}) /);
  2613. if (location.protocol === 'http:' && m && m[1].length <= 6 && m[1] < '044429') {
  2614. assert.ok(data.headers['content-type'] === 'application/octet-stream', 'Content-Type 正确');
  2615. } else {
  2616. assert.ok(data.headers['content-type'] === 'application/zip', 'Content-Type 正确');
  2617. }
  2618. done();
  2619. });
  2620. });
  2621. });
  2622. test('sliceUploadFile blob Content-Type null application/octet-stream', function (done, assert) {
  2623. cos.sliceUploadFile({
  2624. Bucket: config.Bucket,
  2625. Region: config.Region,
  2626. Key: '1',
  2627. Body: util.createFile({size: 1}),
  2628. }, function (err, data) {
  2629. cos.headObject({
  2630. Bucket: config.Bucket,
  2631. Region: config.Region,
  2632. Key: '1',
  2633. }, function (err, data) {
  2634. assert.ok(data.headers['content-type'] === 'application/octet-stream', 'Content-Type 正确');
  2635. done();
  2636. });
  2637. });
  2638. });
  2639. });
  2640. group('Cache-Control', function (val) {
  2641. var isNormalCacheControl = function (val) {
  2642. return val === undefined
  2643. || val === 'no-cache'
  2644. || val === 'max-age=259200'
  2645. // || val === 'no-cache, max-age=259200' // IE 10
  2646. // || val === 'no-cache, max-age=7200' // firefox
  2647. };
  2648. // putObject
  2649. test('putObject Cache-Control: null -> Cache-Control: null or max-age=259200', function (done, assert) {
  2650. cos.putObject({
  2651. Bucket: config.Bucket,
  2652. Region: config.Region,
  2653. Key: '1mb.zip',
  2654. Body: '',
  2655. }, function (err, data) {
  2656. cos.headObject({
  2657. Bucket: config.Bucket,
  2658. Region: config.Region,
  2659. Key: '1mb.zip',
  2660. }, function (err, data) {
  2661. assert.ok(isNormalCacheControl(data.headers['cache-control']), 'cache-control 正确');
  2662. done();
  2663. });
  2664. });
  2665. });
  2666. test('putObject Cache-Control: max-age=7200 -> Cache-Control: max-age=7200', function (done, assert) {
  2667. cos.putObject({
  2668. Bucket: config.Bucket,
  2669. Region: config.Region,
  2670. Key: '1mb.zip',
  2671. Body: '',
  2672. CacheControl: 'max-age=7200',
  2673. }, function (err, data) {
  2674. cos.headObject({
  2675. Bucket: config.Bucket,
  2676. Region: config.Region,
  2677. Key: '1mb.zip',
  2678. }, function (err, data) {
  2679. assert.ok(data.headers['cache-control'] === 'max-age=7200', 'cache-control 正确');
  2680. done();
  2681. });
  2682. });
  2683. });
  2684. test('putObject Cache-Control: no-cache -> Cache-Control: no-cache', function (done, assert) {
  2685. cos.putObject({
  2686. Bucket: config.Bucket,
  2687. Region: config.Region,
  2688. Key: '1mb.zip',
  2689. Body: '',
  2690. CacheControl: 'no-cache',
  2691. }, function (err, data) {
  2692. cos.headObject({
  2693. Bucket: config.Bucket,
  2694. Region: config.Region,
  2695. Key: '1mb.zip',
  2696. }, function (err, data) {
  2697. assert.ok(data.headers['cache-control'] === 'no-cache' || data.headers['cache-control'] === 'no-cache, max-age=259200', 'cache-control 正确');
  2698. done();
  2699. });
  2700. });
  2701. });
  2702. // sliceUploadFile
  2703. test('sliceUploadFile Cache-Control: null -> Cache-Control: null or max-age=259200', function (done, assert) {
  2704. cos.sliceUploadFile({
  2705. Bucket: config.Bucket,
  2706. Region: config.Region,
  2707. Key: '1mb.zip',
  2708. Body: '',
  2709. }, function (err, data) {
  2710. cos.headObject({
  2711. Bucket: config.Bucket,
  2712. Region: config.Region,
  2713. Key: '1mb.zip',
  2714. }, function (err, data) {
  2715. assert.ok(data.headers['cache-control'] === undefined || data.headers['cache-control'] === 'max-age=259200' || data.headers['cache-control'] === 'no-cache, max-age=259200', 'cache-control 正确');
  2716. done();
  2717. });
  2718. });
  2719. });
  2720. test('sliceUploadFile Cache-Control: max-age=7200 -> Cache-Control: max-age=7200', function (done, assert) {
  2721. cos.sliceUploadFile({
  2722. Bucket: config.Bucket,
  2723. Region: config.Region,
  2724. Key: '1mb.zip',
  2725. Body: '',
  2726. CacheControl: 'max-age=7200',
  2727. }, function (err, data) {
  2728. cos.headObject({
  2729. Bucket: config.Bucket,
  2730. Region: config.Region,
  2731. Key: '1mb.zip',
  2732. }, function (err, data) {
  2733. assert.ok(data.headers['cache-control'] === 'max-age=7200', 'cache-control 正确');
  2734. done();
  2735. });
  2736. });
  2737. });
  2738. test('sliceUploadFile Cache-Control: no-cache -> Cache-Control: no-cache', function (done, assert) {
  2739. cos.sliceUploadFile({
  2740. Bucket: config.Bucket,
  2741. Region: config.Region,
  2742. Key: '1mb.zip',
  2743. Body: '',
  2744. CacheControl: 'no-cache',
  2745. }, function (err, data) {
  2746. cos.headObject({
  2747. Bucket: config.Bucket,
  2748. Region: config.Region,
  2749. Key: '1mb.zip',
  2750. }, function (err, data) {
  2751. assert.ok(data.headers['cache-control'] === 'no-cache' || data.headers['cache-control'] === 'no-cache, max-age=259200', 'cache-control 正确');
  2752. done();
  2753. });
  2754. });
  2755. });
  2756. });
  2757. group('BucketLogging', function () {
  2758. var TargetBucket = config.Bucket;
  2759. var TargetPrefix = 'bucket-logging-prefix' + Date.now().toString(36) + '/';
  2760. var BucketLoggingStatus = {
  2761. LoggingEnabled: {
  2762. TargetBucket: TargetBucket,
  2763. TargetPrefix: TargetPrefix
  2764. }
  2765. };
  2766. test('putBucketLogging(), getBucketLogging()', function (done, assert) {
  2767. cos.putBucketLogging({
  2768. Bucket: config.Bucket,
  2769. Region: config.Region,
  2770. BucketLoggingStatus: BucketLoggingStatus
  2771. }, function (err, data) {
  2772. assert.ok(!err);
  2773. cos.getBucketLogging({
  2774. Bucket: config.Bucket,
  2775. Region: config.Region
  2776. }, function (err, data) {
  2777. assert.ok(comparePlainObject(BucketLoggingStatus, data.BucketLoggingStatus));
  2778. done();
  2779. });
  2780. });
  2781. });
  2782. test('putBucketLogging() 删除 logging 配置', function (done, assert) {
  2783. cos.putBucketLogging({
  2784. Bucket: config.Bucket,
  2785. Region: config.Region,
  2786. BucketLoggingStatus: ''
  2787. }, function (err, data) {
  2788. assert.ok(!err);
  2789. cos.getBucketLogging({
  2790. Bucket: config.Bucket,
  2791. Region: config.Region
  2792. }, function (err, data) {
  2793. assert.ok(data.BucketLoggingStatus === '');
  2794. done();
  2795. });
  2796. });
  2797. });
  2798. });
  2799. group('BucketInventory', function () {
  2800. var TargetBucket = config.Bucket;
  2801. var InventoryConfiguration = {
  2802. Id: 'inventory_test',
  2803. IsEnabled: 'true',
  2804. Destination: {
  2805. COSBucketDestination: {
  2806. Format: 'CSV',
  2807. AccountId: config.Uin,
  2808. Bucket: 'qcs::cos:' + config.Region + '::' + TargetBucket,
  2809. Prefix: 'inventory_prefix_1',
  2810. Encryption: {
  2811. SSECOS: ''
  2812. }
  2813. }
  2814. },
  2815. Schedule: {
  2816. Frequency: 'Daily'
  2817. },
  2818. Filter: {
  2819. Prefix: 'myPrefix'
  2820. },
  2821. IncludedObjectVersions: 'All',
  2822. OptionalFields: [
  2823. 'Size'
  2824. ]
  2825. };
  2826. var InventoryConfigurationNoEncryption = {
  2827. Id: 'inventory_test',
  2828. IsEnabled: 'true',
  2829. Destination: {
  2830. COSBucketDestination: {
  2831. Format: 'CSV',
  2832. AccountId: config.Uin,
  2833. Bucket: 'qcs::cos:' + config.Region + '::' + TargetBucket,
  2834. Prefix: 'inventory_prefix_1'
  2835. }
  2836. },
  2837. Schedule: {
  2838. Frequency: 'Daily'
  2839. },
  2840. Filter: {
  2841. Prefix: 'myPrefix'
  2842. },
  2843. IncludedObjectVersions: 'All',
  2844. OptionalFields: [
  2845. 'Size'
  2846. ]
  2847. };
  2848. test('putBucketInventory(), getBucketInventory()', function (done, assert) {
  2849. cos.putBucketInventory({
  2850. Bucket: config.Bucket,
  2851. Region: config.Region,
  2852. Id: InventoryConfiguration.Id,
  2853. InventoryConfiguration: InventoryConfiguration
  2854. }, function (err, data) {
  2855. assert.ok(!err);
  2856. cos.getBucketInventory({
  2857. Bucket: config.Bucket,
  2858. Region: config.Region,
  2859. Id: InventoryConfiguration.Id
  2860. }, function (err, data) {
  2861. assert.ok(comparePlainObject(InventoryConfiguration, data.InventoryConfiguration));
  2862. done();
  2863. });
  2864. });
  2865. });
  2866. test('listBucketInventory()', function (done, assert) {
  2867. cos.listBucketInventory({
  2868. Bucket: config.Bucket,
  2869. Region: config.Region
  2870. }, function (err, data) {
  2871. var targetInventory;
  2872. data.InventoryConfigurations.forEach(function (item) {
  2873. if (item.Id === InventoryConfiguration.Id) {
  2874. targetInventory = item;
  2875. }
  2876. });
  2877. assert.ok(comparePlainObject(InventoryConfiguration, targetInventory));
  2878. assert.ok(data.IsTruncated === 'false' || data.IsTruncated === 'true');
  2879. done();
  2880. });
  2881. });
  2882. test('putBucketInventory() 不设置 SSECOS', function (done, assert) {
  2883. cos.putBucketInventory({
  2884. Bucket: config.Bucket,
  2885. Region: config.Region,
  2886. Id: InventoryConfigurationNoEncryption.Id,
  2887. InventoryConfiguration: InventoryConfigurationNoEncryption
  2888. }, function (err, data) {
  2889. assert.ok(!err);
  2890. cos.getBucketInventory({
  2891. Bucket: config.Bucket,
  2892. Region: config.Region,
  2893. Id: InventoryConfigurationNoEncryption.Id
  2894. }, function (err, data) {
  2895. assert.ok(comparePlainObject(InventoryConfigurationNoEncryption, data.InventoryConfiguration));
  2896. done();
  2897. });
  2898. });
  2899. });
  2900. test('deleteBucketInventory()', function (done, assert) {
  2901. cos.deleteBucketInventory({
  2902. Bucket: config.Bucket,
  2903. Region: config.Region,
  2904. Id: InventoryConfiguration.Id
  2905. }, function (err, data) {
  2906. assert.ok(!err);
  2907. cos.getBucketInventory({
  2908. Bucket: config.Bucket,
  2909. Region: config.Region,
  2910. Id: InventoryConfiguration.Id
  2911. }, function (err, data) {
  2912. assert.ok(err && err.statusCode === 404);
  2913. done();
  2914. });
  2915. });
  2916. });
  2917. });
  2918. var tagging2str = function (obj) {
  2919. var arr = [];
  2920. obj.forEach(function (v) {
  2921. arr.push(v.Key + '=' + encodeURIComponent(v.Value));
  2922. })
  2923. return arr.join('&');
  2924. }
  2925. group('上传带 tagging', function () {
  2926. var Tags = [
  2927. {Key: "k1", Value: "v1"},
  2928. {Key: "k2", Value: "v2"},
  2929. ];
  2930. var key = '1.txt';
  2931. test('putObject 带 x-cos-tagging', function (done, assert) {
  2932. Tags[0].Value = Date.now().toString(36);
  2933. var tagStr = tagging2str(Tags);
  2934. // 调用方法
  2935. cos.putObject({
  2936. Bucket: config.Bucket,
  2937. Region: config.Region,
  2938. Key: key,
  2939. Body: 'hello!',
  2940. Headers: {
  2941. 'x-cos-tagging': tagStr,
  2942. },
  2943. }, function (err1, data1) {
  2944. cos.headObject({
  2945. Bucket: config.Bucket,
  2946. Region: config.Region,
  2947. Key: key,
  2948. }, function (err2, data2) {
  2949. var taggingCount = data2 && data2.headers['x-cos-tagging-count'];
  2950. assert.ok(taggingCount === '2', '返回 x-cos-tagging-count: ' + taggingCount);
  2951. cos.getObjectTagging({
  2952. Bucket: config.Bucket,
  2953. Region: config.Region,
  2954. Key: key,
  2955. }, function (err3, data3) {
  2956. assert.ok(comparePlainObject(Tags, data3.Tags));
  2957. done();
  2958. });
  2959. });
  2960. });
  2961. });
  2962. // test('sliceUploadFile 带 x-cos-tagging', function (done, assert) {
  2963. // Tags[0].Value = Date.now().toString(36);
  2964. // var tagStr = tagging2str(Tags);
  2965. // // 调用方法
  2966. // cos.sliceUploadFile({
  2967. // Bucket: config.Bucket,
  2968. // Region: config.Region,
  2969. // Key: key,
  2970. // Body: 'hello!',
  2971. // Headers: {
  2972. // 'x-cos-tagging': tagStr,
  2973. // },
  2974. // }, function (err1, data1) {
  2975. // cos.headObject({
  2976. // Bucket: config.Bucket,
  2977. // Region: config.Region,
  2978. // Key: key,
  2979. // }, function (err2, data2) {
  2980. // var taggingCount = data2 && data2.headers['x-cos-tagging-count'];
  2981. // assert.ok(taggingCount === '1', '返回 x-cos-tagging-count: ' + taggingCount);
  2982. // cos.getObjectTagging({
  2983. // Bucket: config.Bucket,
  2984. // Region: config.Region,
  2985. // Key: key,
  2986. // }, function (err3, data3) {
  2987. // assert.ok(data3 && data3.Tags && comparePlainObject(Tags, data3.Tags));
  2988. // done();
  2989. // });
  2990. // });
  2991. // });
  2992. // });
  2993. });
  2994. group('ObjectTagging', function () {
  2995. var key = '1.txt';
  2996. var Tags = [
  2997. {Key: "k1", Value: "v1"},
  2998. {Key: "k2", Value: "v2"},
  2999. ];
  3000. test('putObjectTagging(),getObjectTagging()', function (done, assert) {
  3001. Tags[0].Value = Date.now().toString(36);
  3002. cos.putObjectTagging({
  3003. Bucket: config.Bucket,
  3004. Region: config.Region,
  3005. Key: key,
  3006. Tagging: {
  3007. Tags: Tags
  3008. },
  3009. }, function (err, data) {
  3010. assert.ok(!err);
  3011. setTimeout(function () {
  3012. cos.getObjectTagging({
  3013. Bucket: config.Bucket,
  3014. Region: config.Region,
  3015. Key: key,
  3016. }, function (err, data) {
  3017. assert.ok(comparePlainObject(Tags, data.Tags));
  3018. done();
  3019. });
  3020. }, 1000);
  3021. });
  3022. });
  3023. test('deleteObjectTagging()', function (done, assert) {
  3024. cos.deleteObjectTagging({
  3025. Bucket: config.Bucket,
  3026. Region: config.Region,
  3027. Key: key,
  3028. }, function (err, data) {
  3029. assert.ok(!err);
  3030. setTimeout(function () {
  3031. cos.getObjectTagging({
  3032. Bucket: config.Bucket,
  3033. Region: config.Region,
  3034. Key: key,
  3035. }, function (err, data) {
  3036. assert.ok(comparePlainObject([], data.Tags));
  3037. done();
  3038. });
  3039. }, 1000);
  3040. });
  3041. });
  3042. });
  3043. group('getBucketAccelerate', function () {
  3044. test('putBucketAccelerate(),getBucketAccelerate() Enabled', function (done, assert) {
  3045. cos.putBucketAccelerate({
  3046. Bucket: config.Bucket,
  3047. Region: config.Region,
  3048. AccelerateConfiguration: {
  3049. Status: 'Enabled', // Suspended、Enabled
  3050. },
  3051. }, function (err, data) {
  3052. assert.ok(!err);
  3053. setTimeout(function () {
  3054. cos.getBucketAccelerate({
  3055. Bucket: config.Bucket,
  3056. Region: config.Region,
  3057. }, function (err2, data2) {
  3058. assert.ok(data2 && data2.AccelerateConfiguration && data2.AccelerateConfiguration.Status === 'Enabled');
  3059. done();
  3060. });
  3061. }, 2000);
  3062. });
  3063. });
  3064. test('putBucketAccelerate(),getBucketAccelerate() Suspended', function (done, assert) {
  3065. cos.putBucketAccelerate({
  3066. Bucket: config.Bucket,
  3067. Region: config.Region,
  3068. AccelerateConfiguration: {
  3069. Status: 'Suspended', // Suspended、Enabled
  3070. },
  3071. }, function (err, data) {
  3072. assert.ok(!err);
  3073. setTimeout(function () {
  3074. cos.getBucketAccelerate({
  3075. Bucket: config.Bucket,
  3076. Region: config.Region,
  3077. }, function (err2, data2) {
  3078. assert.ok(data2 && data2.AccelerateConfiguration && data2.AccelerateConfiguration.Status === 'Suspended');
  3079. done();
  3080. });
  3081. }, 1000);
  3082. });
  3083. });
  3084. });
  3085. group('Promise', function () {
  3086. test('headBucket callback', function (done, assert) {
  3087. var res = cos.headBucket({
  3088. Bucket: config.Bucket,
  3089. Region: config.Region,
  3090. }, function (err, data) {
  3091. assert.ok(!err && data);
  3092. done();
  3093. });
  3094. assert.ok(!res);
  3095. });
  3096. test('Promise() getObjectUrl', function (done, assert) {
  3097. var res = cos.getObjectUrl({
  3098. Bucket: config.Bucket,
  3099. Region: config.Region,
  3100. Key: '123.txt',
  3101. });
  3102. assert.ok(!res.then);
  3103. done();
  3104. });
  3105. test('Promise() headBucket', function (done, assert) {
  3106. cos.headBucket({
  3107. Bucket: config.Bucket,
  3108. Region: config.Region,
  3109. }).then(function (data) {
  3110. assert.ok(data);
  3111. done();
  3112. }).catch(function () {
  3113. assert.ok(false);
  3114. done();
  3115. });
  3116. });
  3117. test('headBucket callback', function (done, assert) {
  3118. var res = cos.headBucket({
  3119. Bucket: config.Bucket,
  3120. Region: config.Region,
  3121. }, function (err, data) {
  3122. assert.ok(!err && data);
  3123. done();
  3124. });
  3125. assert.ok(!res);
  3126. });
  3127. test('Promise() headBucket error', function (done, assert) {
  3128. cos.headBucket({
  3129. Bucket: config.Bucket,
  3130. Region: config.Region + '/',
  3131. }).then(function (data) {
  3132. assert.ok(!data);
  3133. done();
  3134. }).catch(function (err) {
  3135. assert.ok(err && err.message === 'Region format error.');
  3136. done();
  3137. });
  3138. });
  3139. });
  3140. group('Query 的键值带有特殊字符', function () {
  3141. test('getAuth() 特殊字符', function (done, assert) {
  3142. var content = Date.now().toString();
  3143. var key = '1.txt';
  3144. cos.putObject({
  3145. Bucket: config.Bucket,
  3146. Region: config.Region,
  3147. Key: key,
  3148. Body: content,
  3149. }, function (err, data) {
  3150. var str = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,./;\'[]\\-=0987654321`~!@#$%^&*()_+{}|":>?<';
  3151. var qs = {};
  3152. qs[str] = str;
  3153. cos.options.getAuthorization({
  3154. Method: 'get',
  3155. Key: key,
  3156. Scope: [{
  3157. action: 'GetObject',
  3158. bucket: config.Bucket,
  3159. region: config.Region,
  3160. prefix: key,
  3161. }],
  3162. Query: qs,
  3163. }, function (AuthData) {
  3164. if (typeof AuthData === 'string') {
  3165. AuthData = {Authorization: AuthData};
  3166. }
  3167. if (!AuthData.Authorization) {
  3168. AuthData.Authorization = COS.getAuthorization({
  3169. SecretId: AuthData.TmpSecretId,
  3170. SecretKey: AuthData.TmpSecretKey,
  3171. Method: 'get',
  3172. Key: key,
  3173. SystemClockOffset: cos.options.SystemClockOffset,
  3174. });
  3175. }
  3176. var link = 'http://' + config.Bucket + '.cos.' + config.Region + '.myqcloud.com' + '/' +
  3177. camSafeUrlEncode(key).replace(/%2F/g, '/') + '?' + AuthData.Authorization +
  3178. (AuthData.SecurityToken ? '&x-cos-security-token=' + AuthData.SecurityToken : '') +
  3179. '&' + camSafeUrlEncode(str) + '=' + camSafeUrlEncode(str);
  3180. request({
  3181. method: 'GET',
  3182. url: link,
  3183. }, function (err, response, body) {
  3184. assert.ok(response.statusCode === 200);
  3185. assert.ok(body === content);
  3186. done();
  3187. });
  3188. });
  3189. });
  3190. });
  3191. test('getAuth() 特殊字符 ?sign=', function (done, assert) {
  3192. var content = Date.now().toString();
  3193. var key = '1.txt';
  3194. cos.putObject({
  3195. Bucket: config.Bucket,
  3196. Region: config.Region,
  3197. Key: key,
  3198. Body: content,
  3199. }, function (err, data) {
  3200. var str = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,./;\'[]\\-=0987654321`~!@#$%^&*()_+{}|":>?<';
  3201. var qs = {};
  3202. qs[str] = str;
  3203. cos.options.getAuthorization({
  3204. Method: 'get',
  3205. Key: key,
  3206. Scope: [{
  3207. action: 'GetObject',
  3208. bucket: config.Bucket,
  3209. region: config.Region,
  3210. prefix: key,
  3211. }],
  3212. Query: qs,
  3213. }, function (AuthData) {
  3214. if (typeof AuthData === 'string') {
  3215. AuthData = {Authorization: AuthData};
  3216. }
  3217. if (!AuthData.Authorization) {
  3218. AuthData.Authorization = COS.getAuthorization({
  3219. SecretId: AuthData.TmpSecretId,
  3220. SecretKey: AuthData.TmpSecretKey,
  3221. Method: 'get',
  3222. Key: key,
  3223. SystemClockOffset: cos.options.SystemClockOffset,
  3224. });
  3225. }
  3226. var link = 'http://' + config.Bucket + '.cos.' + config.Region + '.myqcloud.com' + '/' +
  3227. camSafeUrlEncode(key).replace(/%2F/g, '/') +
  3228. '?sign=' + camSafeUrlEncode(AuthData.Authorization) +
  3229. (AuthData.SecurityToken ? '&x-cos-security-token=' + AuthData.SecurityToken : '') +
  3230. '&' + camSafeUrlEncode(str) + '=' + camSafeUrlEncode(str);
  3231. request({
  3232. method: 'GET',
  3233. url: link,
  3234. }, function (err, response, body) {
  3235. assert.ok(response.statusCode === 200);
  3236. assert.ok(body === content);
  3237. done();
  3238. });
  3239. });
  3240. });
  3241. });
  3242. });
  3243. group('selectObjectContent(),selectObjectContentStream()', function () {
  3244. var key = '1.json';
  3245. var selectJsonOpt = {
  3246. Bucket: config.Bucket,
  3247. Region: config.Region,
  3248. Key: key,
  3249. SelectType: 2,
  3250. SelectRequest: {
  3251. Expression: "Select * from COSObject",
  3252. ExpressionType: "SQL",
  3253. InputSerialization: {JSON: {Type: "DOCUMENT",},},
  3254. OutputSerialization: {JSON: {RecordDelimiter: "\n"},},
  3255. RequestProgress: {Enabled: "FALSE"}
  3256. },
  3257. };
  3258. test('selectObjectContent', function (done, assert) {
  3259. var time = Date.now();
  3260. var content = `{"a":123,"b":"中文${time}","c":{"d":456}}`;
  3261. cos.putObject({
  3262. Bucket: config.Bucket,
  3263. Region: config.Region,
  3264. Key: key,
  3265. Body: content,
  3266. }, function (err, data) {
  3267. cos.selectObjectContent(selectJsonOpt, function (err, data) {
  3268. assert.ok(data.Payload === content + '\n');
  3269. done();
  3270. });
  3271. });
  3272. });
  3273. test('selectObjectContent', function (done, assert) {
  3274. var time = Date.now();
  3275. var content = `{"a":123,"b":"${time}","c":{"d":456}`;
  3276. cos.putObject({
  3277. Bucket: config.Bucket,
  3278. Region: config.Region,
  3279. Key: key,
  3280. Body: content,
  3281. }, function (err, data) {
  3282. var bufList = [];
  3283. cos.selectObjectContent(selectJsonOpt, function (err, data) {
  3284. assert.ok(err);
  3285. done();
  3286. });
  3287. });
  3288. });
  3289. });
  3290. group('BucketReplication', function () {
  3291. var prepared = false;
  3292. var repBucket = config.Bucket.replace(/^(.*)(-\d+)$/, '$1-replication$2')
  3293. var repBucketName = repBucket.replace(/(-\d+)$/, '')
  3294. var repRegion = 'ap-chengdu';
  3295. var prepareBucket = function (callback) {
  3296. cos.putBucket({
  3297. Bucket: repBucket,
  3298. Region: repRegion,
  3299. }, function (err, data) {
  3300. cos.putBucketVersioning({
  3301. Bucket: config.Bucket,
  3302. Region: config.Region,
  3303. VersioningConfiguration: {
  3304. Status: 'Enabled'
  3305. }
  3306. }, function (err, data) {
  3307. cos.putBucketVersioning({
  3308. Bucket: repBucket,
  3309. Region: repRegion,
  3310. VersioningConfiguration: {
  3311. Status: 'Enabled'
  3312. }
  3313. }, function (err, data) {
  3314. prepared = true
  3315. callback();
  3316. });
  3317. });
  3318. });
  3319. };
  3320. test('putBucketReplication();getBucketReplication()', function (done, assert) {
  3321. var ruleId = Date.now().toString(36);
  3322. prepareBucket(function () {
  3323. cos.putBucketReplication({
  3324. Bucket: config.Bucket,
  3325. Region: config.Region,
  3326. ReplicationConfiguration: {
  3327. Role: "qcs::cam::uin/10001:uin/10001",
  3328. Rules: [{
  3329. ID: ruleId,
  3330. Status: "Enabled",
  3331. Prefix: "sync/",
  3332. Destination: {
  3333. Bucket: `qcs:id/0:cos:${repRegion}:appid/${AppId}:${repBucketName}`,
  3334. }
  3335. }]
  3336. }
  3337. }, function (err, data) {
  3338. assert.ok(!err);
  3339. cos.getBucketReplication({
  3340. Bucket: config.Bucket,
  3341. Region: config.Region,
  3342. }, function (err, data) {
  3343. assert.ok(data.ReplicationConfiguration.Rules[0].ID === ruleId);
  3344. done();
  3345. });
  3346. });
  3347. });
  3348. });
  3349. test('deleteBucketReplication()', function (done, assert) {
  3350. cos.deleteBucketReplication({
  3351. Bucket: config.Bucket,
  3352. Region: config.Region,
  3353. VersioningConfiguration: {
  3354. Status: 'Suspended'
  3355. }
  3356. }, function (err, data) {
  3357. assert.ok(!err);
  3358. setTimeout(function () {
  3359. cos.getBucketReplication({
  3360. Bucket: config.Bucket,
  3361. Region: config.Region,
  3362. }, function (err, data) {
  3363. assert.ok(err && err.statusCode === 404);
  3364. done();
  3365. });
  3366. }, 2000);
  3367. });
  3368. });
  3369. });
  3370. group('putBucketVersioning(),getBucketVersioning()', function () {
  3371. test('Enabled', function (done, assert) {
  3372. cos.deleteBucketReplication({
  3373. Bucket: config.Bucket,
  3374. Region: config.Region,
  3375. VersioningConfiguration: {
  3376. Status: "Enabled"
  3377. }
  3378. }, function (err, data) {
  3379. cos.putBucketVersioning({
  3380. Bucket: config.Bucket,
  3381. Region: config.Region,
  3382. VersioningConfiguration: {
  3383. Status: "Enabled"
  3384. }
  3385. }, function (err, data) {
  3386. setTimeout(function () {
  3387. cos.getBucketVersioning({
  3388. Bucket: config.Bucket,
  3389. Region: config.Region,
  3390. }, function (err, data) {
  3391. assert.ok(data.VersioningConfiguration.Status === 'Enabled');
  3392. done();
  3393. });
  3394. }, 2000);
  3395. });
  3396. });
  3397. });
  3398. test('Suspended', function (done, assert) {
  3399. cos.putBucketVersioning({
  3400. Bucket: config.Bucket,
  3401. Region: config.Region,
  3402. VersioningConfiguration: {
  3403. Status: 'Suspended'
  3404. }
  3405. }, function (err, data) {
  3406. assert.ok(!err);
  3407. setTimeout(function () {
  3408. cos.getBucketVersioning({
  3409. Bucket: config.Bucket,
  3410. Region: config.Region,
  3411. }, function (err, data) {
  3412. console.log(data.VersioningConfiguration.Status);
  3413. assert.ok(data.VersioningConfiguration.Status === 'Suspended');
  3414. done();
  3415. });
  3416. }, 2000);
  3417. });
  3418. });
  3419. });
  3420. group('BucketOrigin', function () {
  3421. test('putBucketOrigin(),getBucketOrigin()', function (done, assert) {
  3422. var prefix = Date.now().toString(36) + '/';
  3423. cos.putBucketOrigin({
  3424. Bucket: config.Bucket,
  3425. Region: config.Region,
  3426. OriginRule: [{
  3427. OriginType: 'Mirror',
  3428. OriginCondition: {HTTPStatusCode: 404, Prefix: ''},
  3429. OriginParameter: {
  3430. Protocol: 'HTTP',
  3431. FollowQueryString: 'true',
  3432. HttpHeader: {
  3433. NewHttpHeader: {
  3434. Header: [{
  3435. Key: 'a',
  3436. Value: 'a'
  3437. }]
  3438. }
  3439. },
  3440. FollowRedirection: 'true',
  3441. HttpRedirectCode: ['301', '302']
  3442. },
  3443. OriginInfo: {
  3444. HostInfo: {HostName: 'qq.com'},
  3445. FileInfo: {
  3446. PrefixConfiguration: {Prefix: prefix},
  3447. SuffixConfiguration: {Suffix: '.jpg'}
  3448. }
  3449. },
  3450. RulePriority: 1
  3451. }]
  3452. }, function (err, data) {
  3453. assert.ok(!err);
  3454. cos.getBucketOrigin({
  3455. Bucket: config.Bucket,
  3456. Region: config.Region
  3457. }, function (err, data) {
  3458. assert.ok(data.OriginRule[0].OriginInfo.FileInfo.PrefixConfiguration.Prefix === prefix);
  3459. done();
  3460. });
  3461. });
  3462. });
  3463. test('deleteBucketOrigin()', function (done, assert) {
  3464. cos.deleteBucketOrigin({
  3465. Bucket: config.Bucket,
  3466. Region: config.Region
  3467. }, function (err, data) {
  3468. assert.ok(!err);
  3469. setTimeout(function () {
  3470. cos.getBucketOrigin({
  3471. Bucket: config.Bucket,
  3472. Region: config.Region
  3473. }, function (err, data) {
  3474. assert.ok(err);
  3475. done();
  3476. });
  3477. }, 2000);
  3478. });
  3479. });
  3480. });
  3481. group('BucketReferer', function () {
  3482. test('putBucketReferer(),getBucketReferer()', function (done, assert) {
  3483. var conf = {
  3484. Status: 'Enabled',
  3485. RefererType: 'White-List',
  3486. DomainList: {
  3487. Domains: [
  3488. Date.now().toString(36) + '.qq.com',
  3489. '*.qcloud.com',
  3490. ]
  3491. },
  3492. EmptyReferConfiguration: 'Allow',
  3493. };
  3494. cos.putBucketReferer({
  3495. Bucket: config.Bucket,
  3496. Region: config.Region,
  3497. RefererConfiguration: conf
  3498. }, function (err, data) {
  3499. assert.ok(!err);
  3500. setTimeout(function () {
  3501. cos.getBucketReferer({
  3502. Bucket: config.Bucket,
  3503. Region: config.Region
  3504. }, function (err, data) {
  3505. assert.ok(comparePlainObject(conf, data.RefererConfiguration));
  3506. done();
  3507. });
  3508. }, 2000);
  3509. });
  3510. });
  3511. });
  3512. group('restoreObject()', function () {
  3513. test('restoreObject()', function (done, assert) {
  3514. cos.putObject({
  3515. Bucket: config.Bucket,
  3516. Region: config.Region,
  3517. Key: '1.jpg',
  3518. Body: '123',
  3519. StorageClass: 'ARCHIVE'
  3520. }, function (err, data) {
  3521. assert.ok(!err);
  3522. cos.restoreObject({
  3523. Bucket: config.Bucket,
  3524. Region: config.Region,
  3525. Key: '1.jpg',
  3526. RestoreRequest: {
  3527. Days: 1,
  3528. CASJobParameters: {
  3529. Tier: 'Expedited'
  3530. }
  3531. },
  3532. }, function (err, data) {
  3533. assert.ok(data && Math.floor(data.statusCode / 100) === 2);
  3534. done();
  3535. });
  3536. });
  3537. });
  3538. });
  3539. group('uploadFile()', function () {
  3540. // 高级上传
  3541. test('uploadFile() 高级上传', function (done, assert) {
  3542. var filename = '3m.zip';
  3543. var blob = util.createFile({size: 1024 * 1024 * 3});
  3544. cos.uploadFile({
  3545. Bucket: config.Bucket,
  3546. Region: config.Region,
  3547. Key: filename,
  3548. Body: blob,
  3549. }, function (err, data) {
  3550. console.log(data);
  3551. assert.ok(!err);
  3552. done();
  3553. });
  3554. });
  3555. test('uploadFile() 高级上传内容为空', function (done, assert) {
  3556. var filename = '3m.zip';
  3557. cos.uploadFile({
  3558. Bucket: config.Bucket,
  3559. Region: config.Region,
  3560. Key: filename,
  3561. Body: '',
  3562. }, function (err, data) {
  3563. assert.ok(!err);
  3564. done();
  3565. });
  3566. });
  3567. test('uploadFile() 高级上传 大于5mb则分块上传', function (done, assert) {
  3568. var filename = '3m.zip';
  3569. var blob = util.createFile({size: 1024 * 1024 * 3});
  3570. cos.uploadFile({
  3571. Bucket: config.Bucket,
  3572. Region: config.Region,
  3573. Key: filename,
  3574. Body: blob,
  3575. SliceSize: 1024 * 1024 * 5,
  3576. }, function (err, data) {
  3577. assert.ok(!err);
  3578. done();
  3579. });
  3580. });
  3581. });
  3582. group('uploadFiles()', function () {
  3583. test('uploadFiles()', function (done, assert) {
  3584. var filename = '1.zip';
  3585. cos.uploadFiles({
  3586. files: [{
  3587. Bucket: config.Bucket,
  3588. Region: config.Region,
  3589. Key: filename,
  3590. Body: '123456',
  3591. }],
  3592. }, function (err, data) {
  3593. assert.ok(!data.files.error);
  3594. done();
  3595. });
  3596. });
  3597. });
  3598. group('multipartAbort()', function () {
  3599. test('multipartAbort()', function (done, assert) {
  3600. var Key = '1.jpg'
  3601. cos.multipartInit({
  3602. Bucket: config.Bucket,
  3603. Region: config.Region,
  3604. Key: Key,
  3605. }, function (err, data) {
  3606. assert.ok(!err);
  3607. var UploadId = data.UploadId;
  3608. cos.multipartAbort({
  3609. Bucket: config.Bucket,
  3610. Region: config.Region,
  3611. Key: Key,
  3612. UploadId: UploadId,
  3613. }, function (err, data) {
  3614. assert.ok(!err);
  3615. cos.multipartListPart({
  3616. Bucket: config.Bucket,
  3617. Region: config.Region,
  3618. Key: Key,
  3619. UploadId: UploadId,
  3620. }, function (err, data) {
  3621. assert.ok(err);
  3622. done();
  3623. });
  3624. });
  3625. });
  3626. });
  3627. });
  3628. group('sliceUploadFile() 续传', function () {
  3629. test('multipartAbort()', function (done, assert) {
  3630. var Key = '3.zip'
  3631. cos.multipartInit({
  3632. Bucket: config.Bucket,
  3633. Region: config.Region,
  3634. Key: Key,
  3635. }, function (err, data) {
  3636. assert.ok(!err);
  3637. var UploadId = data.UploadId;
  3638. cos.multipartUpload({
  3639. Bucket: config.Bucket,
  3640. Region: config.Region,
  3641. Key: Key,
  3642. UploadId: UploadId,
  3643. PartNumber: 1,
  3644. Body: util.createFile({size: 1024 * 1024}),
  3645. }, function (err, data) {
  3646. assert.ok(!err);
  3647. cos.sliceUploadFile({
  3648. Bucket: config.Bucket,
  3649. Region: config.Region,
  3650. Key: Key,
  3651. Body: util.createFile({size: 1024 * 1024 * 3}),
  3652. ChunkSize: 1024 * 1024,
  3653. }, function (err, data) {
  3654. assert.ok(data);
  3655. done();
  3656. });
  3657. });
  3658. });
  3659. });
  3660. });
  3661. group('appendObject', function () {
  3662. test('appendObject()', function (done, assert) {
  3663. cos.headObject({
  3664. Bucket: config.Bucket, // Bucket 格式:test-1250000000
  3665. Region: config.Region,
  3666. Key: 'append.txt', /* 必须 */
  3667. }, function(err, data) {
  3668. assert.ok(!err);
  3669. if (err) return console.log(err);
  3670. // 首先取到要追加的文件当前长度,即需要上送的Position
  3671. var position = data.headers['content-length'];
  3672. cos.appendObject({
  3673. Bucket: config.Bucket, // Bucket 格式:test-1250000000
  3674. Region: config.Region,
  3675. Key: 'append.txt', /* 必须 */
  3676. Body: '66666',
  3677. Position: position,
  3678. },
  3679. function(err, data) {
  3680. assert.ok(!err);
  3681. done();
  3682. })
  3683. });
  3684. });
  3685. });
  3686. group('数据万象', function () {
  3687. test('describeMediaBuckets()', function (done, assert) {
  3688. var host = 'ci.' + config.Region + '.myqcloud.com';
  3689. var url = 'https://' + host + '/mediabucket';
  3690. cos.request({
  3691. Bucket: config.Bucket,
  3692. Region: config.Region,
  3693. Method: 'GET',
  3694. Key: 'mediabucket', /** 固定值,必须 */
  3695. Url: url,
  3696. Query: {
  3697. pageNumber: '1', /** 第几页,非必须 */
  3698. pageSize: '10', /** 每页个数,非必须 */
  3699. // regions: 'ap-chengdu', /** 地域信息,例如'ap-beijing',支持多个值用逗号分隔如'ap-shanghai,ap-beijing',非必须 */
  3700. // bucketNames: 'test-1250000000', /** 存储桶名称,精确搜索,例如'test-1250000000',支持多个值用逗号分隔如'test1-1250000000,test2-1250000000',非必须 */
  3701. // bucketName: 'test', /** 存储桶名称前缀,前缀搜索,例如'test',支持多个值用逗号分隔如'test1,test2',非必须 */
  3702. }
  3703. }, function (err, data) {
  3704. assert.ok(!err);
  3705. done();
  3706. });
  3707. });
  3708. test('getMediaInfo()', function (done, assert) {
  3709. cos.request({
  3710. Bucket: config.Bucket,
  3711. Region: config.Region,
  3712. Method: 'GET',
  3713. Key: 'test.mp4',
  3714. Query: {
  3715. 'ci-process': 'videoinfo' /** 固定值,必须 */
  3716. }
  3717. }, function (err, data) {
  3718. assert.ok(!err);
  3719. done();
  3720. });
  3721. });
  3722. test('getSnapshot()', function (done, assert) {
  3723. cos.request({
  3724. Bucket: config.Bucket,
  3725. Region: config.Region,
  3726. Method: 'GET',
  3727. Key: 'test.mp4',
  3728. Query: {
  3729. 'ci-process': 'snapshot', /** 固定值,必须 */
  3730. time: 1, /** 截图的时间点,单位为秒,必须 */
  3731. // width: 0, /** 截图的宽,非必须 */
  3732. // height: 0, /** 截图的高,非必须 */
  3733. // format: 'jpg', /** 截图的格式,支持 jpg 和 png,默认 jpg,非必须 */
  3734. // rotate: 'auto', /** 图片旋转方式,默认为'auto',非必须 */
  3735. // mode: 'exactframe', /** 截帧方式,默认为'exactframe',非必须 */
  3736. },
  3737. RawBody: true,
  3738. },
  3739. function(err, data){
  3740. assert.ok(!err);
  3741. done();
  3742. });
  3743. });
  3744. });