cos-js-sdk-v5.js 382 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882
  1. (function webpackUniversalModuleDefinition(root, factory) {
  2. if(typeof exports === 'object' && typeof module === 'object')
  3. module.exports = factory();
  4. else if(typeof define === 'function' && define.amd)
  5. define([], factory);
  6. else if(typeof exports === 'object')
  7. exports["COS"] = factory();
  8. else
  9. root["COS"] = factory();
  10. })(typeof self !== 'undefined' ? self : this, function() {
  11. return /******/ (function(modules) { // webpackBootstrap
  12. /******/ // The module cache
  13. /******/ var installedModules = {};
  14. /******/
  15. /******/ // The require function
  16. /******/ function __webpack_require__(moduleId) {
  17. /******/
  18. /******/ // Check if module is in cache
  19. /******/ if(installedModules[moduleId]) {
  20. /******/ return installedModules[moduleId].exports;
  21. /******/ }
  22. /******/ // Create a new module (and put it into the cache)
  23. /******/ var module = installedModules[moduleId] = {
  24. /******/ i: moduleId,
  25. /******/ l: false,
  26. /******/ exports: {}
  27. /******/ };
  28. /******/
  29. /******/ // Execute the module function
  30. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  31. /******/
  32. /******/ // Flag the module as loaded
  33. /******/ module.l = true;
  34. /******/
  35. /******/ // Return the exports of the module
  36. /******/ return module.exports;
  37. /******/ }
  38. /******/
  39. /******/
  40. /******/ // expose the modules object (__webpack_modules__)
  41. /******/ __webpack_require__.m = modules;
  42. /******/
  43. /******/ // expose the module cache
  44. /******/ __webpack_require__.c = installedModules;
  45. /******/
  46. /******/ // define getter function for harmony exports
  47. /******/ __webpack_require__.d = function(exports, name, getter) {
  48. /******/ if(!__webpack_require__.o(exports, name)) {
  49. /******/ Object.defineProperty(exports, name, {
  50. /******/ configurable: false,
  51. /******/ enumerable: true,
  52. /******/ get: getter
  53. /******/ });
  54. /******/ }
  55. /******/ };
  56. /******/
  57. /******/ // getDefaultExport function for compatibility with non-harmony modules
  58. /******/ __webpack_require__.n = function(module) {
  59. /******/ var getter = module && module.__esModule ?
  60. /******/ function getDefault() { return module['default']; } :
  61. /******/ function getModuleExports() { return module; };
  62. /******/ __webpack_require__.d(getter, 'a', getter);
  63. /******/ return getter;
  64. /******/ };
  65. /******/
  66. /******/ // Object.prototype.hasOwnProperty.call
  67. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  68. /******/
  69. /******/ // __webpack_public_path__
  70. /******/ __webpack_require__.p = "/dist/";
  71. /******/
  72. /******/ // Load entry module and return exports
  73. /******/ return __webpack_require__(__webpack_require__.s = 6);
  74. /******/ })
  75. /************************************************************************/
  76. /******/ ([
  77. /* 0 */
  78. /***/ (function(module, exports, __webpack_require__) {
  79. "use strict";
  80. /* WEBPACK VAR INJECTION */(function(process) {
  81. var md5 = __webpack_require__(8);
  82. var CryptoJS = __webpack_require__(11);
  83. var xml2json = __webpack_require__(12);
  84. var json2xml = __webpack_require__(17);
  85. function camSafeUrlEncode(str) {
  86. return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A');
  87. }
  88. function getObjectKeys(obj, forKey) {
  89. var list = [];
  90. for (var key in obj) {
  91. if (obj.hasOwnProperty(key)) {
  92. list.push(forKey ? camSafeUrlEncode(key).toLowerCase() : key);
  93. }
  94. }
  95. return list.sort(function (a, b) {
  96. a = a.toLowerCase();
  97. b = b.toLowerCase();
  98. return a === b ? 0 : a > b ? 1 : -1;
  99. });
  100. };
  101. /**
  102. * obj转为string
  103. * @param {Object} obj 需要转的对象,必须
  104. * @param {Boolean} lowerCaseKey key是否转为小写,默认false,非必须
  105. * @return {String} data 返回字符串
  106. */
  107. var obj2str = function (obj, lowerCaseKey) {
  108. var i, key, val;
  109. var list = [];
  110. var keyList = getObjectKeys(obj);
  111. for (i = 0; i < keyList.length; i++) {
  112. key = keyList[i];
  113. val = obj[key] === undefined || obj[key] === null ? '' : '' + obj[key];
  114. key = lowerCaseKey ? camSafeUrlEncode(key).toLowerCase() : camSafeUrlEncode(key);
  115. val = camSafeUrlEncode(val) || '';
  116. list.push(key + '=' + val);
  117. }
  118. return list.join('&');
  119. };
  120. // 可以签入签名的headers
  121. var signHeaders = ['content-disposition', 'content-encoding', 'content-length', 'content-md5', 'expect', 'host', 'if-match', 'if-modified-since', 'if-none-match', 'if-unmodified-since', 'origin', 'range', 'response-cache-control', 'response-content-disposition', 'response-content-encoding', 'response-content-language', 'response-content-type', 'response-expires', 'transfer-encoding', 'versionid'];
  122. var getSignHeaderObj = function (headers) {
  123. var signHeaderObj = {};
  124. for (var i in headers) {
  125. var key = i.toLowerCase();
  126. if (key.indexOf('x-cos-') > -1 || signHeaders.indexOf(key) > -1) {
  127. signHeaderObj[i] = headers[i];
  128. }
  129. }
  130. return signHeaderObj;
  131. };
  132. //测试用的key后面可以去掉
  133. var getAuth = function (opt) {
  134. opt = opt || {};
  135. var SecretId = opt.SecretId;
  136. var SecretKey = opt.SecretKey;
  137. var KeyTime = opt.KeyTime;
  138. var method = (opt.method || opt.Method || 'get').toLowerCase();
  139. var queryParams = clone(opt.Query || opt.params || {});
  140. var headers = getSignHeaderObj(clone(opt.Headers || opt.headers || {}));
  141. var Key = opt.Key || '';
  142. var pathname;
  143. if (opt.UseRawKey) {
  144. pathname = opt.Pathname || opt.pathname || '/' + Key;
  145. } else {
  146. pathname = opt.Pathname || opt.pathname || Key;
  147. pathname.indexOf('/') !== 0 && (pathname = '/' + pathname);
  148. }
  149. // ForceSignHost明确传入false才不加入host签名
  150. var forceSignHost = opt.ForceSignHost === false ? false : true;
  151. // 如果有传入存储桶且需要强制签名,那么签名默认加 Host 参与计算,避免跨桶访问
  152. if (!headers.Host && !headers.host && opt.Bucket && opt.Region && forceSignHost) headers.Host = opt.Bucket + '.cos.' + opt.Region + '.myqcloud.com';
  153. if (!SecretId) throw new Error('missing param SecretId');
  154. if (!SecretKey) throw new Error('missing param SecretKey');
  155. // 签名有效起止时间
  156. var now = Math.round(getSkewTime(opt.SystemClockOffset) / 1000) - 1;
  157. var exp = now;
  158. var Expires = opt.Expires || opt.expires;
  159. if (Expires === undefined) {
  160. exp += 900; // 签名过期时间为当前 + 900s
  161. } else {
  162. exp += Expires * 1 || 0;
  163. }
  164. // 要用到的 Authorization 参数列表
  165. var qSignAlgorithm = 'sha1';
  166. var qAk = SecretId;
  167. var qSignTime = KeyTime || now + ';' + exp;
  168. var qKeyTime = KeyTime || now + ';' + exp;
  169. var qHeaderList = getObjectKeys(headers, true).join(';').toLowerCase();
  170. var qUrlParamList = getObjectKeys(queryParams, true).join(';').toLowerCase();
  171. // 签名算法说明文档:https://www.qcloud.com/document/product/436/7778
  172. // 步骤一:计算 SignKey
  173. var signKey = CryptoJS.HmacSHA1(qKeyTime, SecretKey).toString();
  174. // 步骤二:构成 FormatString
  175. var formatString = [method, pathname, util.obj2str(queryParams, true), util.obj2str(headers, true), ''].join('\n');
  176. // 步骤三:计算 StringToSign
  177. var stringToSign = ['sha1', qSignTime, CryptoJS.SHA1(formatString).toString(), ''].join('\n');
  178. // 步骤四:计算 Signature
  179. var qSignature = CryptoJS.HmacSHA1(stringToSign, signKey).toString();
  180. // 步骤五:构造 Authorization
  181. var authorization = ['q-sign-algorithm=' + qSignAlgorithm, 'q-ak=' + qAk, 'q-sign-time=' + qSignTime, 'q-key-time=' + qKeyTime, 'q-header-list=' + qHeaderList, 'q-url-param-list=' + qUrlParamList, 'q-signature=' + qSignature].join('&');
  182. return authorization;
  183. };
  184. var readIntBE = function (chunk, size, offset) {
  185. var bytes = size / 8;
  186. var buf = chunk.slice(offset, offset + bytes);
  187. new Uint8Array(buf).reverse();
  188. return new { 8: Uint8Array, 16: Uint16Array, 32: Uint32Array }[size](buf)[0];
  189. };
  190. var buf2str = function (chunk, start, end, isUtf8) {
  191. var buf = chunk.slice(start, end);
  192. var str = '';
  193. new Uint8Array(buf).forEach(function (charCode) {
  194. str += String.fromCharCode(charCode);
  195. });
  196. if (isUtf8) str = decodeURIComponent(escape(str));
  197. return str;
  198. };
  199. var parseSelectPayload = function (chunk) {
  200. var header = {};
  201. var body = buf2str(chunk);
  202. var result = { records: [] };
  203. while (chunk.byteLength) {
  204. var totalLength = readIntBE(chunk, 32, 0);
  205. var headerLength = readIntBE(chunk, 32, 4);
  206. var payloadRestLength = totalLength - headerLength - 16;
  207. var offset = 0;
  208. var content;
  209. chunk = chunk.slice(12);
  210. // 获取 Message 的 header 信息
  211. while (offset < headerLength) {
  212. var headerNameLength = readIntBE(chunk, 8, offset);
  213. var headerName = buf2str(chunk, offset + 1, offset + 1 + headerNameLength);
  214. var headerValueLength = readIntBE(chunk, 16, offset + headerNameLength + 2);
  215. var headerValue = buf2str(chunk, offset + headerNameLength + 4, offset + headerNameLength + 4 + headerValueLength);
  216. header[headerName] = headerValue;
  217. offset += headerNameLength + 4 + headerValueLength;
  218. }
  219. if (header[':event-type'] === 'Records') {
  220. content = buf2str(chunk, offset, offset + payloadRestLength, true);
  221. result.records.push(content);
  222. } else if (header[':event-type'] === 'Stats') {
  223. content = buf2str(chunk, offset, offset + payloadRestLength, true);
  224. result.stats = util.xml2json(content).Stats;
  225. } else if (header[':event-type'] === 'error') {
  226. var errCode = header[':error-code'];
  227. var errMessage = header[':error-message'];
  228. var err = new Error(errMessage);
  229. err.message = errMessage;
  230. err.name = err.code = errCode;
  231. result.error = err;
  232. } else if (['Progress', 'Continuation', 'End'].includes(header[':event-type'])) {
  233. // do nothing
  234. }
  235. chunk = chunk.slice(offset + payloadRestLength + 4);
  236. }
  237. return {
  238. payload: result.records.join(''),
  239. body: body
  240. };
  241. };
  242. var getSourceParams = function (source) {
  243. var parser = this.options.CopySourceParser;
  244. if (parser) return parser(source);
  245. var m = source.match(/^([^.]+-\d+)\.cos(v6|-cdc)?\.([^.]+)\.myqcloud\.com\/(.+)$/);
  246. if (!m) return null;
  247. return { Bucket: m[1], Region: m[3], Key: m[4] };
  248. };
  249. var noop = function () {};
  250. // 清除对象里值为的 undefined 或 null 的属性
  251. var clearKey = function (obj) {
  252. var retObj = {};
  253. for (var key in obj) {
  254. if (obj.hasOwnProperty(key) && obj[key] !== undefined && obj[key] !== null) {
  255. retObj[key] = obj[key];
  256. }
  257. }
  258. return retObj;
  259. };
  260. var readAsBinaryString = function (blob, callback) {
  261. var readFun;
  262. var fr = new FileReader();
  263. if (FileReader.prototype.readAsBinaryString) {
  264. readFun = FileReader.prototype.readAsBinaryString;
  265. fr.onload = function () {
  266. callback(this.result);
  267. };
  268. } else if (FileReader.prototype.readAsArrayBuffer) {
  269. // 在 ie11 添加 readAsBinaryString 兼容
  270. readFun = function (fileData) {
  271. var binary = "";
  272. var pt = this;
  273. var reader = new FileReader();
  274. reader.onload = function (e) {
  275. var bytes = new Uint8Array(reader.result);
  276. var length = bytes.byteLength;
  277. for (var i = 0; i < length; i++) {
  278. binary += String.fromCharCode(bytes[i]);
  279. }
  280. callback(binary);
  281. };
  282. reader.readAsArrayBuffer(fileData);
  283. };
  284. } else {
  285. console.error('FileReader not support readAsBinaryString');
  286. }
  287. readFun.call(fr, blob);
  288. };
  289. var fileSliceNeedCopy = function () {
  290. var compareVersion = function (a, b) {
  291. a = a.split('.');
  292. b = b.split('.');
  293. for (var i = 0; i < b.length; i++) {
  294. if (a[i] !== b[i]) {
  295. return parseInt(a[i]) > parseInt(b[i]) ? 1 : -1;
  296. }
  297. }
  298. return 0;
  299. };
  300. var check = function (ua) {
  301. if (!ua) return false;
  302. var ChromeVersion = (ua.match(/Chrome\/([.\d]+)/) || [])[1];
  303. var QBCoreVersion = (ua.match(/QBCore\/([.\d]+)/) || [])[1];
  304. var QQBrowserVersion = (ua.match(/QQBrowser\/([.\d]+)/) || [])[1];
  305. var need = ChromeVersion && compareVersion(ChromeVersion, '53.0.2785.116') < 0 && QBCoreVersion && compareVersion(QBCoreVersion, '3.53.991.400') < 0 && QQBrowserVersion && compareVersion(QQBrowserVersion, '9.0.2524.400') <= 0 || false;
  306. return need;
  307. };
  308. return check(typeof navigator !== 'undefined' && navigator.userAgent);
  309. }();
  310. // 获取文件分片
  311. var fileSlice = function (file, start, end, isUseToUpload, callback) {
  312. var blob;
  313. if (file.slice) {
  314. blob = file.slice(start, end);
  315. } else if (file.mozSlice) {
  316. blob = file.mozSlice(start, end);
  317. } else if (file.webkitSlice) {
  318. blob = file.webkitSlice(start, end);
  319. }
  320. if (isUseToUpload && fileSliceNeedCopy) {
  321. var reader = new FileReader();
  322. reader.onload = function (e) {
  323. blob = null;
  324. callback(new Blob([reader.result]));
  325. };
  326. reader.readAsArrayBuffer(blob);
  327. } else {
  328. callback(blob);
  329. }
  330. };
  331. // 获取文件内容的 MD5
  332. var getBodyMd5 = function (UploadCheckContentMd5, Body, callback, onProgress) {
  333. callback = callback || noop;
  334. if (UploadCheckContentMd5) {
  335. if (typeof Body === 'string') {
  336. callback(util.md5(Body, true));
  337. } else if (Blob && Body instanceof Blob) {
  338. util.getFileMd5(Body, function (err, md5) {
  339. callback(md5);
  340. }, onProgress);
  341. } else {
  342. callback();
  343. }
  344. } else {
  345. callback();
  346. }
  347. };
  348. // 获取文件 md5 值
  349. var md5ChunkSize = 1024 * 1024;
  350. var getFileMd5 = function (blob, callback, onProgress) {
  351. var size = blob.size;
  352. var loaded = 0;
  353. var md5ctx = md5.getCtx();
  354. var next = function (start) {
  355. if (start >= size) {
  356. var hash = md5ctx.digest('hex');
  357. callback(null, hash);
  358. return;
  359. }
  360. var end = Math.min(size, start + md5ChunkSize);
  361. util.fileSlice(blob, start, end, false, function (chunk) {
  362. readAsBinaryString(chunk, function (content) {
  363. chunk = null;
  364. md5ctx = md5ctx.update(content, true);
  365. loaded += content.length;
  366. content = null;
  367. if (onProgress) onProgress({ loaded: loaded, total: size, percent: Math.round(loaded / size * 10000) / 10000 });
  368. next(start + md5ChunkSize);
  369. });
  370. });
  371. };
  372. next(0);
  373. };
  374. function clone(obj) {
  375. return map(obj, function (v) {
  376. return typeof v === 'object' && v !== null ? clone(v) : v;
  377. });
  378. }
  379. function attr(obj, name, defaultValue) {
  380. return obj && name in obj ? obj[name] : defaultValue;
  381. }
  382. function extend(target, source) {
  383. each(source, function (val, key) {
  384. target[key] = source[key];
  385. });
  386. return target;
  387. }
  388. function isArray(arr) {
  389. return arr instanceof Array;
  390. }
  391. function isInArray(arr, item) {
  392. var flag = false;
  393. for (var i = 0; i < arr.length; i++) {
  394. if (item === arr[i]) {
  395. flag = true;
  396. break;
  397. }
  398. }
  399. return flag;
  400. }
  401. function makeArray(arr) {
  402. return isArray(arr) ? arr : [arr];
  403. }
  404. function each(obj, fn) {
  405. for (var i in obj) {
  406. if (obj.hasOwnProperty(i)) {
  407. fn(obj[i], i);
  408. }
  409. }
  410. }
  411. function map(obj, fn) {
  412. var o = isArray(obj) ? [] : {};
  413. for (var i in obj) {
  414. if (obj.hasOwnProperty(i)) {
  415. o[i] = fn(obj[i], i);
  416. }
  417. }
  418. return o;
  419. }
  420. function filter(obj, fn) {
  421. var iaArr = isArray(obj);
  422. var o = iaArr ? [] : {};
  423. for (var i in obj) {
  424. if (obj.hasOwnProperty(i)) {
  425. if (fn(obj[i], i)) {
  426. if (iaArr) {
  427. o.push(obj[i]);
  428. } else {
  429. o[i] = obj[i];
  430. }
  431. }
  432. }
  433. }
  434. return o;
  435. }
  436. var binaryBase64 = function (str) {
  437. var i,
  438. len,
  439. char,
  440. res = '';
  441. for (i = 0, len = str.length / 2; i < len; i++) {
  442. char = parseInt(str[i * 2] + str[i * 2 + 1], 16);
  443. res += String.fromCharCode(char);
  444. }
  445. return btoa(res);
  446. };
  447. var uuid = function () {
  448. var S4 = function () {
  449. return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
  450. };
  451. return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
  452. };
  453. var hasMissingParams = function (apiName, params) {
  454. var Bucket = params.Bucket;
  455. var Region = params.Region;
  456. var Key = params.Key;
  457. var Domain = this.options.Domain;
  458. var checkBucket = !Domain || typeof Domain === 'string' && Domain.indexOf('{Bucket}') > -1;
  459. var checkRegion = !Domain || typeof Domain === 'string' && Domain.indexOf('{Region}') > -1;
  460. if (apiName.indexOf('Bucket') > -1 || apiName === 'deleteMultipleObject' || apiName === 'multipartList' || apiName === 'listObjectVersions') {
  461. if (checkBucket && !Bucket) return 'Bucket';
  462. if (checkRegion && !Region) return 'Region';
  463. } else if (apiName.indexOf('Object') > -1 || apiName.indexOf('multipart') > -1 || apiName === 'sliceUploadFile' || apiName === 'abortUploadTask') {
  464. if (checkBucket && !Bucket) return 'Bucket';
  465. if (checkRegion && !Region) return 'Region';
  466. if (!Key) return 'Key';
  467. }
  468. return false;
  469. };
  470. var formatParams = function (apiName, params) {
  471. // 复制参数对象
  472. params = extend({}, params);
  473. // 统一处理 Headers
  474. if (apiName !== 'getAuth' && apiName !== 'getV4Auth' && apiName !== 'getObjectUrl') {
  475. var Headers = params.Headers || {};
  476. if (params && typeof params === 'object') {
  477. (function () {
  478. for (var key in params) {
  479. if (params.hasOwnProperty(key) && key.indexOf('x-cos-') > -1) {
  480. Headers[key] = params[key];
  481. }
  482. }
  483. })();
  484. var headerMap = {
  485. // params headers
  486. 'x-cos-mfa': 'MFA',
  487. 'Content-MD5': 'ContentMD5',
  488. 'Content-Length': 'ContentLength',
  489. 'Content-Type': 'ContentType',
  490. 'Expect': 'Expect',
  491. 'Expires': 'Expires',
  492. 'Cache-Control': 'CacheControl',
  493. 'Content-Disposition': 'ContentDisposition',
  494. 'Content-Encoding': 'ContentEncoding',
  495. 'Range': 'Range',
  496. 'If-Modified-Since': 'IfModifiedSince',
  497. 'If-Unmodified-Since': 'IfUnmodifiedSince',
  498. 'If-Match': 'IfMatch',
  499. 'If-None-Match': 'IfNoneMatch',
  500. 'x-cos-copy-source': 'CopySource',
  501. 'x-cos-copy-source-Range': 'CopySourceRange',
  502. 'x-cos-metadata-directive': 'MetadataDirective',
  503. 'x-cos-copy-source-If-Modified-Since': 'CopySourceIfModifiedSince',
  504. 'x-cos-copy-source-If-Unmodified-Since': 'CopySourceIfUnmodifiedSince',
  505. 'x-cos-copy-source-If-Match': 'CopySourceIfMatch',
  506. 'x-cos-copy-source-If-None-Match': 'CopySourceIfNoneMatch',
  507. 'x-cos-acl': 'ACL',
  508. 'x-cos-grant-read': 'GrantRead',
  509. 'x-cos-grant-write': 'GrantWrite',
  510. 'x-cos-grant-full-control': 'GrantFullControl',
  511. 'x-cos-grant-read-acp': 'GrantReadAcp',
  512. 'x-cos-grant-write-acp': 'GrantWriteAcp',
  513. 'x-cos-storage-class': 'StorageClass',
  514. 'x-cos-traffic-limit': 'TrafficLimit',
  515. 'x-cos-mime-limit': 'MimeLimit',
  516. // SSE-C
  517. 'x-cos-server-side-encryption-customer-algorithm': 'SSECustomerAlgorithm',
  518. 'x-cos-server-side-encryption-customer-key': 'SSECustomerKey',
  519. 'x-cos-server-side-encryption-customer-key-MD5': 'SSECustomerKeyMD5',
  520. // SSE-COS、SSE-KMS
  521. 'x-cos-server-side-encryption': 'ServerSideEncryption',
  522. 'x-cos-server-side-encryption-cos-kms-key-id': 'SSEKMSKeyId',
  523. 'x-cos-server-side-encryption-context': 'SSEContext'
  524. };
  525. util.each(headerMap, function (paramKey, headerKey) {
  526. if (params[paramKey] !== undefined) {
  527. Headers[headerKey] = params[paramKey];
  528. }
  529. });
  530. params.Headers = clearKey(Headers);
  531. }
  532. }
  533. return params;
  534. };
  535. var apiWrapper = function (apiName, apiFn) {
  536. return function (params, callback) {
  537. var self = this;
  538. // 处理参数
  539. if (typeof params === 'function') {
  540. callback = params;
  541. params = {};
  542. }
  543. // 整理参数格式
  544. params = formatParams(apiName, params);
  545. // 代理回调函数
  546. var formatResult = function (result) {
  547. if (result && result.headers) {
  548. result.headers['x-cos-request-id'] && (result.RequestId = result.headers['x-cos-request-id']);
  549. result.headers['x-ci-request-id'] && (result.RequestId = result.headers['x-ci-request-id']);
  550. result.headers['x-cos-version-id'] && (result.VersionId = result.headers['x-cos-version-id']);
  551. result.headers['x-cos-delete-marker'] && (result.DeleteMarker = result.headers['x-cos-delete-marker']);
  552. }
  553. return result;
  554. };
  555. var _callback = function (err, data) {
  556. callback && callback(formatResult(err), formatResult(data));
  557. };
  558. var checkParams = function () {
  559. if (apiName !== 'getService' && apiName !== 'abortUploadTask') {
  560. // 判断参数是否完整
  561. var missingResult = hasMissingParams.call(self, apiName, params);
  562. if (missingResult) {
  563. return 'missing param ' + missingResult;
  564. }
  565. // 判断 region 格式
  566. if (params.Region) {
  567. if (self.options.CompatibilityMode) {
  568. if (!/^([a-z\d-.]+)$/.test(params.Region)) {
  569. return 'Region format error.';
  570. }
  571. } else {
  572. if (params.Region.indexOf('cos.') > -1) {
  573. return 'param Region should not be start with "cos."';
  574. } else if (!/^([a-z\d-]+)$/.test(params.Region)) {
  575. return 'Region format error.';
  576. }
  577. }
  578. // 判断 region 格式
  579. if (!self.options.CompatibilityMode && params.Region.indexOf('-') === -1 && params.Region !== 'yfb' && params.Region !== 'default' && params.Region !== 'accelerate') {
  580. console.warn('warning: param Region format error, find help here: https://cloud.tencent.com/document/product/436/6224');
  581. }
  582. }
  583. // 兼容不带 AppId 的 Bucket
  584. if (params.Bucket) {
  585. if (!/^([a-z\d-]+)-(\d+)$/.test(params.Bucket)) {
  586. if (params.AppId) {
  587. params.Bucket = params.Bucket + '-' + params.AppId;
  588. } else if (self.options.AppId) {
  589. params.Bucket = params.Bucket + '-' + self.options.AppId;
  590. } else {
  591. return 'Bucket should format as "test-1250000000".';
  592. }
  593. }
  594. if (params.AppId) {
  595. console.warn('warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g Bucket:"test-1250000000" ).');
  596. delete params.AppId;
  597. }
  598. }
  599. // 如果 Key 是 / 开头,强制去掉第一个 /
  600. if (!self.options.UseRawKey && params.Key && params.Key.substr(0, 1) === '/') {
  601. params.Key = params.Key.substr(1);
  602. }
  603. }
  604. };
  605. var errMsg = checkParams();
  606. var isSync = apiName === 'getAuth' || apiName === 'getObjectUrl';
  607. if (typeof Promise === 'function' && !isSync && !callback) {
  608. return new Promise(function (resolve, reject) {
  609. callback = function (err, data) {
  610. err ? reject(err) : resolve(data);
  611. };
  612. if (errMsg) return _callback(util.error(new Error(errMsg)));
  613. apiFn.call(self, params, _callback);
  614. });
  615. } else {
  616. if (errMsg) return _callback(util.error(new Error(errMsg)));
  617. var res = apiFn.call(self, params, _callback);
  618. if (isSync) return res;
  619. }
  620. };
  621. };
  622. var throttleOnProgress = function (total, onProgress) {
  623. var self = this;
  624. var size0 = 0;
  625. var size1 = 0;
  626. var time0 = Date.now();
  627. var time1;
  628. var timer;
  629. function update() {
  630. timer = 0;
  631. if (onProgress && typeof onProgress === 'function') {
  632. time1 = Date.now();
  633. var speed = Math.max(0, Math.round((size1 - size0) / ((time1 - time0) / 1000) * 100) / 100) || 0;
  634. var percent;
  635. if (size1 === 0 && total === 0) {
  636. percent = 1;
  637. } else {
  638. percent = Math.floor(size1 / total * 100) / 100 || 0;
  639. }
  640. time0 = time1;
  641. size0 = size1;
  642. try {
  643. onProgress({ loaded: size1, total: total, speed: speed, percent: percent });
  644. } catch (e) {}
  645. }
  646. }
  647. return function (info, immediately) {
  648. if (info) {
  649. size1 = info.loaded;
  650. total = info.total;
  651. }
  652. if (immediately) {
  653. clearTimeout(timer);
  654. update();
  655. } else {
  656. if (timer) return;
  657. timer = setTimeout(update, self.options.ProgressInterval);
  658. }
  659. };
  660. };
  661. var getFileSize = function (api, params, callback) {
  662. var size;
  663. if (typeof params.Body === 'string') {
  664. params.Body = new Blob([params.Body], { type: 'text/plain' });
  665. } else if (params.Body instanceof ArrayBuffer) {
  666. params.Body = new Blob([params.Body]);
  667. }
  668. if (params.Body && (params.Body instanceof Blob || params.Body.toString() === '[object File]' || params.Body.toString() === '[object Blob]')) {
  669. size = params.Body.size;
  670. } else {
  671. callback(util.error(new Error('params body format error, Only allow File|Blob|String.')));
  672. return;
  673. }
  674. params.ContentLength = size;
  675. callback(null, size);
  676. };
  677. // 获取调正的时间戳
  678. var getSkewTime = function (offset) {
  679. return Date.now() + (offset || 0);
  680. };
  681. var error = function (err, opt) {
  682. var sourceErr = err;
  683. err.message = err.message || null;
  684. if (typeof opt === 'string') {
  685. err.error = opt;
  686. err.message = opt;
  687. } else if (typeof opt === 'object' && opt !== null) {
  688. extend(err, opt);
  689. if (opt.code || opt.name) err.code = opt.code || opt.name;
  690. if (opt.message) err.message = opt.message;
  691. if (opt.stack) err.stack = opt.stack;
  692. }
  693. if (typeof Object.defineProperty === 'function') {
  694. Object.defineProperty(err, 'name', { writable: true, enumerable: false });
  695. Object.defineProperty(err, 'message', { enumerable: true });
  696. }
  697. err.name = opt && opt.name || err.name || err.code || 'Error';
  698. if (!err.code) err.code = err.name;
  699. if (!err.error) err.error = clone(sourceErr); // 兼容老的错误格式
  700. return err;
  701. };
  702. var isNode = function () {
  703. return typeof window !== 'object' && typeof process === 'object' && "function" === 'function';
  704. };
  705. var isCIHost = function (url) {
  706. return (/^https?:\/\/([^/]+\.)?ci\.[^/]+/.test(url)
  707. );
  708. };
  709. var util = {
  710. noop: noop,
  711. formatParams: formatParams,
  712. apiWrapper: apiWrapper,
  713. xml2json: xml2json,
  714. json2xml: json2xml,
  715. md5: md5,
  716. clearKey: clearKey,
  717. fileSlice: fileSlice,
  718. getBodyMd5: getBodyMd5,
  719. getFileMd5: getFileMd5,
  720. binaryBase64: binaryBase64,
  721. extend: extend,
  722. isArray: isArray,
  723. isInArray: isInArray,
  724. makeArray: makeArray,
  725. each: each,
  726. map: map,
  727. filter: filter,
  728. clone: clone,
  729. attr: attr,
  730. uuid: uuid,
  731. camSafeUrlEncode: camSafeUrlEncode,
  732. throttleOnProgress: throttleOnProgress,
  733. getFileSize: getFileSize,
  734. getSkewTime: getSkewTime,
  735. error: error,
  736. obj2str: obj2str,
  737. getAuth: getAuth,
  738. parseSelectPayload: parseSelectPayload,
  739. getSourceParams: getSourceParams,
  740. isBrowser: true,
  741. isNode: isNode,
  742. isCIHost: isCIHost
  743. };
  744. module.exports = util;
  745. /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))
  746. /***/ }),
  747. /* 1 */
  748. /***/ (function(module, exports, __webpack_require__) {
  749. "use strict";
  750. /**
  751. * "Shallow freezes" an object to render it immutable.
  752. * Uses `Object.freeze` if available,
  753. * otherwise the immutability is only in the type.
  754. *
  755. * Is used to create "enum like" objects.
  756. *
  757. * @template T
  758. * @param {T} object the object to freeze
  759. * @param {Pick<ObjectConstructor, 'freeze'> = Object} oc `Object` by default,
  760. * allows to inject custom object constructor for tests
  761. * @returns {Readonly<T>}
  762. *
  763. * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
  764. */
  765. function freeze(object, oc) {
  766. if (oc === undefined) {
  767. oc = Object
  768. }
  769. return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object
  770. }
  771. /**
  772. * Since we can not rely on `Object.assign` we provide a simplified version
  773. * that is sufficient for our needs.
  774. *
  775. * @param {Object} target
  776. * @param {Object | null | undefined} source
  777. *
  778. * @returns {Object} target
  779. * @throws TypeError if target is not an object
  780. *
  781. * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
  782. * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign
  783. */
  784. function assign(target, source) {
  785. if (target === null || typeof target !== 'object') {
  786. throw new TypeError('target is not an object')
  787. }
  788. for (var key in source) {
  789. if (Object.prototype.hasOwnProperty.call(source, key)) {
  790. target[key] = source[key]
  791. }
  792. }
  793. return target
  794. }
  795. /**
  796. * All mime types that are allowed as input to `DOMParser.parseFromString`
  797. *
  798. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 MDN
  799. * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype WHATWG HTML Spec
  800. * @see DOMParser.prototype.parseFromString
  801. */
  802. var MIME_TYPE = freeze({
  803. /**
  804. * `text/html`, the only mime type that triggers treating an XML document as HTML.
  805. *
  806. * @see DOMParser.SupportedType.isHTML
  807. * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
  808. * @see https://en.wikipedia.org/wiki/HTML Wikipedia
  809. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
  810. * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec
  811. */
  812. HTML: 'text/html',
  813. /**
  814. * Helper method to check a mime type if it indicates an HTML document
  815. *
  816. * @param {string} [value]
  817. * @returns {boolean}
  818. *
  819. * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
  820. * @see https://en.wikipedia.org/wiki/HTML Wikipedia
  821. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
  822. * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */
  823. isHTML: function (value) {
  824. return value === MIME_TYPE.HTML
  825. },
  826. /**
  827. * `application/xml`, the standard mime type for XML documents.
  828. *
  829. * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration
  830. * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303
  831. * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
  832. */
  833. XML_APPLICATION: 'application/xml',
  834. /**
  835. * `text/html`, an alias for `application/xml`.
  836. *
  837. * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303
  838. * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration
  839. * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
  840. */
  841. XML_TEXT: 'text/xml',
  842. /**
  843. * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace,
  844. * but is parsed as an XML document.
  845. *
  846. * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration
  847. * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec
  848. * @see https://en.wikipedia.org/wiki/XHTML Wikipedia
  849. */
  850. XML_XHTML_APPLICATION: 'application/xhtml+xml',
  851. /**
  852. * `image/svg+xml`,
  853. *
  854. * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration
  855. * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1
  856. * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia
  857. */
  858. XML_SVG_IMAGE: 'image/svg+xml',
  859. })
  860. /**
  861. * Namespaces that are used in this code base.
  862. *
  863. * @see http://www.w3.org/TR/REC-xml-names
  864. */
  865. var NAMESPACE = freeze({
  866. /**
  867. * The XHTML namespace.
  868. *
  869. * @see http://www.w3.org/1999/xhtml
  870. */
  871. HTML: 'http://www.w3.org/1999/xhtml',
  872. /**
  873. * Checks if `uri` equals `NAMESPACE.HTML`.
  874. *
  875. * @param {string} [uri]
  876. *
  877. * @see NAMESPACE.HTML
  878. */
  879. isHTML: function (uri) {
  880. return uri === NAMESPACE.HTML
  881. },
  882. /**
  883. * The SVG namespace.
  884. *
  885. * @see http://www.w3.org/2000/svg
  886. */
  887. SVG: 'http://www.w3.org/2000/svg',
  888. /**
  889. * The `xml:` namespace.
  890. *
  891. * @see http://www.w3.org/XML/1998/namespace
  892. */
  893. XML: 'http://www.w3.org/XML/1998/namespace',
  894. /**
  895. * The `xmlns:` namespace
  896. *
  897. * @see https://www.w3.org/2000/xmlns/
  898. */
  899. XMLNS: 'http://www.w3.org/2000/xmlns/',
  900. })
  901. exports.assign = assign;
  902. exports.freeze = freeze;
  903. exports.MIME_TYPE = MIME_TYPE;
  904. exports.NAMESPACE = NAMESPACE;
  905. /***/ }),
  906. /* 2 */
  907. /***/ (function(module, exports) {
  908. // shim for using process in browser
  909. var process = module.exports = {};
  910. // cached from whatever global is present so that test runners that stub it
  911. // don't break things. But we need to wrap it in a try catch in case it is
  912. // wrapped in strict mode code which doesn't define any globals. It's inside a
  913. // function because try/catches deoptimize in certain engines.
  914. var cachedSetTimeout;
  915. var cachedClearTimeout;
  916. function defaultSetTimout() {
  917. throw new Error('setTimeout has not been defined');
  918. }
  919. function defaultClearTimeout () {
  920. throw new Error('clearTimeout has not been defined');
  921. }
  922. (function () {
  923. try {
  924. if (typeof setTimeout === 'function') {
  925. cachedSetTimeout = setTimeout;
  926. } else {
  927. cachedSetTimeout = defaultSetTimout;
  928. }
  929. } catch (e) {
  930. cachedSetTimeout = defaultSetTimout;
  931. }
  932. try {
  933. if (typeof clearTimeout === 'function') {
  934. cachedClearTimeout = clearTimeout;
  935. } else {
  936. cachedClearTimeout = defaultClearTimeout;
  937. }
  938. } catch (e) {
  939. cachedClearTimeout = defaultClearTimeout;
  940. }
  941. } ())
  942. function runTimeout(fun) {
  943. if (cachedSetTimeout === setTimeout) {
  944. //normal enviroments in sane situations
  945. return setTimeout(fun, 0);
  946. }
  947. // if setTimeout wasn't available but was latter defined
  948. if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
  949. cachedSetTimeout = setTimeout;
  950. return setTimeout(fun, 0);
  951. }
  952. try {
  953. // when when somebody has screwed with setTimeout but no I.E. maddness
  954. return cachedSetTimeout(fun, 0);
  955. } catch(e){
  956. try {
  957. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  958. return cachedSetTimeout.call(null, fun, 0);
  959. } catch(e){
  960. // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
  961. return cachedSetTimeout.call(this, fun, 0);
  962. }
  963. }
  964. }
  965. function runClearTimeout(marker) {
  966. if (cachedClearTimeout === clearTimeout) {
  967. //normal enviroments in sane situations
  968. return clearTimeout(marker);
  969. }
  970. // if clearTimeout wasn't available but was latter defined
  971. if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
  972. cachedClearTimeout = clearTimeout;
  973. return clearTimeout(marker);
  974. }
  975. try {
  976. // when when somebody has screwed with setTimeout but no I.E. maddness
  977. return cachedClearTimeout(marker);
  978. } catch (e){
  979. try {
  980. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  981. return cachedClearTimeout.call(null, marker);
  982. } catch (e){
  983. // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
  984. // Some versions of I.E. have different rules for clearTimeout vs setTimeout
  985. return cachedClearTimeout.call(this, marker);
  986. }
  987. }
  988. }
  989. var queue = [];
  990. var draining = false;
  991. var currentQueue;
  992. var queueIndex = -1;
  993. function cleanUpNextTick() {
  994. if (!draining || !currentQueue) {
  995. return;
  996. }
  997. draining = false;
  998. if (currentQueue.length) {
  999. queue = currentQueue.concat(queue);
  1000. } else {
  1001. queueIndex = -1;
  1002. }
  1003. if (queue.length) {
  1004. drainQueue();
  1005. }
  1006. }
  1007. function drainQueue() {
  1008. if (draining) {
  1009. return;
  1010. }
  1011. var timeout = runTimeout(cleanUpNextTick);
  1012. draining = true;
  1013. var len = queue.length;
  1014. while(len) {
  1015. currentQueue = queue;
  1016. queue = [];
  1017. while (++queueIndex < len) {
  1018. if (currentQueue) {
  1019. currentQueue[queueIndex].run();
  1020. }
  1021. }
  1022. queueIndex = -1;
  1023. len = queue.length;
  1024. }
  1025. currentQueue = null;
  1026. draining = false;
  1027. runClearTimeout(timeout);
  1028. }
  1029. process.nextTick = function (fun) {
  1030. var args = new Array(arguments.length - 1);
  1031. if (arguments.length > 1) {
  1032. for (var i = 1; i < arguments.length; i++) {
  1033. args[i - 1] = arguments[i];
  1034. }
  1035. }
  1036. queue.push(new Item(fun, args));
  1037. if (queue.length === 1 && !draining) {
  1038. runTimeout(drainQueue);
  1039. }
  1040. };
  1041. // v8 likes predictible objects
  1042. function Item(fun, array) {
  1043. this.fun = fun;
  1044. this.array = array;
  1045. }
  1046. Item.prototype.run = function () {
  1047. this.fun.apply(null, this.array);
  1048. };
  1049. process.title = 'browser';
  1050. process.browser = true;
  1051. process.env = {};
  1052. process.argv = [];
  1053. process.version = ''; // empty string to avoid regexp issues
  1054. process.versions = {};
  1055. function noop() {}
  1056. process.on = noop;
  1057. process.addListener = noop;
  1058. process.once = noop;
  1059. process.off = noop;
  1060. process.removeListener = noop;
  1061. process.removeAllListeners = noop;
  1062. process.emit = noop;
  1063. process.prependListener = noop;
  1064. process.prependOnceListener = noop;
  1065. process.listeners = function (name) { return [] }
  1066. process.binding = function (name) {
  1067. throw new Error('process.binding is not supported');
  1068. };
  1069. process.cwd = function () { return '/' };
  1070. process.chdir = function (dir) {
  1071. throw new Error('process.chdir is not supported');
  1072. };
  1073. process.umask = function() { return 0; };
  1074. /***/ }),
  1075. /* 3 */
  1076. /***/ (function(module, exports, __webpack_require__) {
  1077. var conventions = __webpack_require__(1);
  1078. var NAMESPACE = conventions.NAMESPACE;
  1079. /**
  1080. * A prerequisite for `[].filter`, to drop elements that are empty
  1081. * @param {string} input
  1082. * @returns {boolean}
  1083. */
  1084. function notEmptyString (input) {
  1085. return input !== ''
  1086. }
  1087. /**
  1088. * @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace
  1089. * @see https://infra.spec.whatwg.org/#ascii-whitespace
  1090. *
  1091. * @param {string} input
  1092. * @returns {string[]} (can be empty)
  1093. */
  1094. function splitOnASCIIWhitespace(input) {
  1095. // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE
  1096. return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : []
  1097. }
  1098. /**
  1099. * Adds element as a key to current if it is not already present.
  1100. *
  1101. * @param {Record<string, boolean | undefined>} current
  1102. * @param {string} element
  1103. * @returns {Record<string, boolean | undefined>}
  1104. */
  1105. function orderedSetReducer (current, element) {
  1106. if (!current.hasOwnProperty(element)) {
  1107. current[element] = true;
  1108. }
  1109. return current;
  1110. }
  1111. /**
  1112. * @see https://infra.spec.whatwg.org/#ordered-set
  1113. * @param {string} input
  1114. * @returns {string[]}
  1115. */
  1116. function toOrderedSet(input) {
  1117. if (!input) return [];
  1118. var list = splitOnASCIIWhitespace(input);
  1119. return Object.keys(list.reduce(orderedSetReducer, {}))
  1120. }
  1121. /**
  1122. * Uses `list.indexOf` to implement something like `Array.prototype.includes`,
  1123. * which we can not rely on being available.
  1124. *
  1125. * @param {any[]} list
  1126. * @returns {function(any): boolean}
  1127. */
  1128. function arrayIncludes (list) {
  1129. return function(element) {
  1130. return list && list.indexOf(element) !== -1;
  1131. }
  1132. }
  1133. function copy(src,dest){
  1134. for(var p in src){
  1135. dest[p] = src[p];
  1136. }
  1137. }
  1138. /**
  1139. ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
  1140. ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
  1141. */
  1142. function _extends(Class,Super){
  1143. var pt = Class.prototype;
  1144. if(!(pt instanceof Super)){
  1145. function t(){};
  1146. t.prototype = Super.prototype;
  1147. t = new t();
  1148. copy(pt,t);
  1149. Class.prototype = pt = t;
  1150. }
  1151. if(pt.constructor != Class){
  1152. if(typeof Class != 'function'){
  1153. console.error("unknown Class:"+Class)
  1154. }
  1155. pt.constructor = Class
  1156. }
  1157. }
  1158. // Node Types
  1159. var NodeType = {}
  1160. var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
  1161. var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
  1162. var TEXT_NODE = NodeType.TEXT_NODE = 3;
  1163. var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
  1164. var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
  1165. var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
  1166. var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
  1167. var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
  1168. var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
  1169. var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
  1170. var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
  1171. var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
  1172. // ExceptionCode
  1173. var ExceptionCode = {}
  1174. var ExceptionMessage = {};
  1175. var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
  1176. var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
  1177. var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
  1178. var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
  1179. var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
  1180. var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
  1181. var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
  1182. var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
  1183. var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
  1184. var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
  1185. //level2
  1186. var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
  1187. var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
  1188. var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
  1189. var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
  1190. var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
  1191. /**
  1192. * DOM Level 2
  1193. * Object DOMException
  1194. * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
  1195. * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
  1196. */
  1197. function DOMException(code, message) {
  1198. if(message instanceof Error){
  1199. var error = message;
  1200. }else{
  1201. error = this;
  1202. Error.call(this, ExceptionMessage[code]);
  1203. this.message = ExceptionMessage[code];
  1204. if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
  1205. }
  1206. error.code = code;
  1207. if(message) this.message = this.message + ": " + message;
  1208. return error;
  1209. };
  1210. DOMException.prototype = Error.prototype;
  1211. copy(ExceptionCode,DOMException)
  1212. /**
  1213. * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
  1214. * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
  1215. * The items in the NodeList are accessible via an integral index, starting from 0.
  1216. */
  1217. function NodeList() {
  1218. };
  1219. NodeList.prototype = {
  1220. /**
  1221. * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
  1222. * @standard level1
  1223. */
  1224. length:0,
  1225. /**
  1226. * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
  1227. * @standard level1
  1228. * @param index unsigned long
  1229. * Index into the collection.
  1230. * @return Node
  1231. * The node at the indexth position in the NodeList, or null if that is not a valid index.
  1232. */
  1233. item: function(index) {
  1234. return this[index] || null;
  1235. },
  1236. toString:function(isHTML,nodeFilter){
  1237. for(var buf = [], i = 0;i<this.length;i++){
  1238. serializeToString(this[i],buf,isHTML,nodeFilter);
  1239. }
  1240. return buf.join('');
  1241. }
  1242. };
  1243. function LiveNodeList(node,refresh){
  1244. this._node = node;
  1245. this._refresh = refresh
  1246. _updateLiveList(this);
  1247. }
  1248. function _updateLiveList(list){
  1249. var inc = list._node._inc || list._node.ownerDocument._inc;
  1250. if(list._inc != inc){
  1251. var ls = list._refresh(list._node);
  1252. //console.log(ls.length)
  1253. __set__(list,'length',ls.length);
  1254. copy(ls,list);
  1255. list._inc = inc;
  1256. }
  1257. }
  1258. LiveNodeList.prototype.item = function(i){
  1259. _updateLiveList(this);
  1260. return this[i];
  1261. }
  1262. _extends(LiveNodeList,NodeList);
  1263. /**
  1264. * Objects implementing the NamedNodeMap interface are used
  1265. * to represent collections of nodes that can be accessed by name.
  1266. * Note that NamedNodeMap does not inherit from NodeList;
  1267. * NamedNodeMaps are not maintained in any particular order.
  1268. * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index,
  1269. * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
  1270. * and does not imply that the DOM specifies an order to these Nodes.
  1271. * NamedNodeMap objects in the DOM are live.
  1272. * used for attributes or DocumentType entities
  1273. */
  1274. function NamedNodeMap() {
  1275. };
  1276. function _findNodeIndex(list,node){
  1277. var i = list.length;
  1278. while(i--){
  1279. if(list[i] === node){return i}
  1280. }
  1281. }
  1282. function _addNamedNode(el,list,newAttr,oldAttr){
  1283. if(oldAttr){
  1284. list[_findNodeIndex(list,oldAttr)] = newAttr;
  1285. }else{
  1286. list[list.length++] = newAttr;
  1287. }
  1288. if(el){
  1289. newAttr.ownerElement = el;
  1290. var doc = el.ownerDocument;
  1291. if(doc){
  1292. oldAttr && _onRemoveAttribute(doc,el,oldAttr);
  1293. _onAddAttribute(doc,el,newAttr);
  1294. }
  1295. }
  1296. }
  1297. function _removeNamedNode(el,list,attr){
  1298. //console.log('remove attr:'+attr)
  1299. var i = _findNodeIndex(list,attr);
  1300. if(i>=0){
  1301. var lastIndex = list.length-1
  1302. while(i<lastIndex){
  1303. list[i] = list[++i]
  1304. }
  1305. list.length = lastIndex;
  1306. if(el){
  1307. var doc = el.ownerDocument;
  1308. if(doc){
  1309. _onRemoveAttribute(doc,el,attr);
  1310. attr.ownerElement = null;
  1311. }
  1312. }
  1313. }else{
  1314. throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
  1315. }
  1316. }
  1317. NamedNodeMap.prototype = {
  1318. length:0,
  1319. item:NodeList.prototype.item,
  1320. getNamedItem: function(key) {
  1321. // if(key.indexOf(':')>0 || key == 'xmlns'){
  1322. // return null;
  1323. // }
  1324. //console.log()
  1325. var i = this.length;
  1326. while(i--){
  1327. var attr = this[i];
  1328. //console.log(attr.nodeName,key)
  1329. if(attr.nodeName == key){
  1330. return attr;
  1331. }
  1332. }
  1333. },
  1334. setNamedItem: function(attr) {
  1335. var el = attr.ownerElement;
  1336. if(el && el!=this._ownerElement){
  1337. throw new DOMException(INUSE_ATTRIBUTE_ERR);
  1338. }
  1339. var oldAttr = this.getNamedItem(attr.nodeName);
  1340. _addNamedNode(this._ownerElement,this,attr,oldAttr);
  1341. return oldAttr;
  1342. },
  1343. /* returns Node */
  1344. setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
  1345. var el = attr.ownerElement, oldAttr;
  1346. if(el && el!=this._ownerElement){
  1347. throw new DOMException(INUSE_ATTRIBUTE_ERR);
  1348. }
  1349. oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
  1350. _addNamedNode(this._ownerElement,this,attr,oldAttr);
  1351. return oldAttr;
  1352. },
  1353. /* returns Node */
  1354. removeNamedItem: function(key) {
  1355. var attr = this.getNamedItem(key);
  1356. _removeNamedNode(this._ownerElement,this,attr);
  1357. return attr;
  1358. },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
  1359. //for level2
  1360. removeNamedItemNS:function(namespaceURI,localName){
  1361. var attr = this.getNamedItemNS(namespaceURI,localName);
  1362. _removeNamedNode(this._ownerElement,this,attr);
  1363. return attr;
  1364. },
  1365. getNamedItemNS: function(namespaceURI, localName) {
  1366. var i = this.length;
  1367. while(i--){
  1368. var node = this[i];
  1369. if(node.localName == localName && node.namespaceURI == namespaceURI){
  1370. return node;
  1371. }
  1372. }
  1373. return null;
  1374. }
  1375. };
  1376. /**
  1377. * The DOMImplementation interface represents an object providing methods
  1378. * which are not dependent on any particular document.
  1379. * Such an object is returned by the `Document.implementation` property.
  1380. *
  1381. * __The individual methods describe the differences compared to the specs.__
  1382. *
  1383. * @constructor
  1384. *
  1385. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN
  1386. * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core (Initial)
  1387. * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core
  1388. * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core
  1389. * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard
  1390. */
  1391. function DOMImplementation() {
  1392. }
  1393. DOMImplementation.prototype = {
  1394. /**
  1395. * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported.
  1396. * The different implementations fairly diverged in what kind of features were reported.
  1397. * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use.
  1398. *
  1399. * @deprecated It is deprecated and modern browsers return true in all cases.
  1400. *
  1401. * @param {string} feature
  1402. * @param {string} [version]
  1403. * @returns {boolean} always true
  1404. *
  1405. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
  1406. * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
  1407. * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
  1408. */
  1409. hasFeature: function(feature, version) {
  1410. return true;
  1411. },
  1412. /**
  1413. * Creates an XML Document object of the specified type with its document element.
  1414. *
  1415. * __It behaves slightly different from the description in the living standard__:
  1416. * - There is no interface/class `XMLDocument`, it returns a `Document` instance.
  1417. * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared.
  1418. * - this implementation is not validating names or qualified names
  1419. * (when parsing XML strings, the SAX parser takes care of that)
  1420. *
  1421. * @param {string|null} namespaceURI
  1422. * @param {string} qualifiedName
  1423. * @param {DocumentType=null} doctype
  1424. * @returns {Document}
  1425. *
  1426. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
  1427. * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial)
  1428. * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core
  1429. *
  1430. * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
  1431. * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
  1432. * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
  1433. */
  1434. createDocument: function(namespaceURI, qualifiedName, doctype){
  1435. var doc = new Document();
  1436. doc.implementation = this;
  1437. doc.childNodes = new NodeList();
  1438. doc.doctype = doctype || null;
  1439. if (doctype){
  1440. doc.appendChild(doctype);
  1441. }
  1442. if (qualifiedName){
  1443. var root = doc.createElementNS(namespaceURI, qualifiedName);
  1444. doc.appendChild(root);
  1445. }
  1446. return doc;
  1447. },
  1448. /**
  1449. * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`.
  1450. *
  1451. * __This behavior is slightly different from the in the specs__:
  1452. * - this implementation is not validating names or qualified names
  1453. * (when parsing XML strings, the SAX parser takes care of that)
  1454. *
  1455. * @param {string} qualifiedName
  1456. * @param {string} [publicId]
  1457. * @param {string} [systemId]
  1458. * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation
  1459. * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()`
  1460. *
  1461. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN
  1462. * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core
  1463. * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard
  1464. *
  1465. * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
  1466. * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
  1467. * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
  1468. */
  1469. createDocumentType: function(qualifiedName, publicId, systemId){
  1470. var node = new DocumentType();
  1471. node.name = qualifiedName;
  1472. node.nodeName = qualifiedName;
  1473. node.publicId = publicId || '';
  1474. node.systemId = systemId || '';
  1475. return node;
  1476. }
  1477. };
  1478. /**
  1479. * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
  1480. */
  1481. function Node() {
  1482. };
  1483. Node.prototype = {
  1484. firstChild : null,
  1485. lastChild : null,
  1486. previousSibling : null,
  1487. nextSibling : null,
  1488. attributes : null,
  1489. parentNode : null,
  1490. childNodes : null,
  1491. ownerDocument : null,
  1492. nodeValue : null,
  1493. namespaceURI : null,
  1494. prefix : null,
  1495. localName : null,
  1496. // Modified in DOM Level 2:
  1497. insertBefore:function(newChild, refChild){//raises
  1498. return _insertBefore(this,newChild,refChild);
  1499. },
  1500. replaceChild:function(newChild, oldChild){//raises
  1501. this.insertBefore(newChild,oldChild);
  1502. if(oldChild){
  1503. this.removeChild(oldChild);
  1504. }
  1505. },
  1506. removeChild:function(oldChild){
  1507. return _removeChild(this,oldChild);
  1508. },
  1509. appendChild:function(newChild){
  1510. return this.insertBefore(newChild,null);
  1511. },
  1512. hasChildNodes:function(){
  1513. return this.firstChild != null;
  1514. },
  1515. cloneNode:function(deep){
  1516. return cloneNode(this.ownerDocument||this,this,deep);
  1517. },
  1518. // Modified in DOM Level 2:
  1519. normalize:function(){
  1520. var child = this.firstChild;
  1521. while(child){
  1522. var next = child.nextSibling;
  1523. if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
  1524. this.removeChild(next);
  1525. child.appendData(next.data);
  1526. }else{
  1527. child.normalize();
  1528. child = next;
  1529. }
  1530. }
  1531. },
  1532. // Introduced in DOM Level 2:
  1533. isSupported:function(feature, version){
  1534. return this.ownerDocument.implementation.hasFeature(feature,version);
  1535. },
  1536. // Introduced in DOM Level 2:
  1537. hasAttributes:function(){
  1538. return this.attributes.length>0;
  1539. },
  1540. /**
  1541. * Look up the prefix associated to the given namespace URI, starting from this node.
  1542. * **The default namespace declarations are ignored by this method.**
  1543. * See Namespace Prefix Lookup for details on the algorithm used by this method.
  1544. *
  1545. * _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._
  1546. *
  1547. * @param {string | null} namespaceURI
  1548. * @returns {string | null}
  1549. * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix
  1550. * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo
  1551. * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix
  1552. * @see https://github.com/xmldom/xmldom/issues/322
  1553. */
  1554. lookupPrefix:function(namespaceURI){
  1555. var el = this;
  1556. while(el){
  1557. var map = el._nsMap;
  1558. //console.dir(map)
  1559. if(map){
  1560. for(var n in map){
  1561. if(map[n] == namespaceURI){
  1562. return n;
  1563. }
  1564. }
  1565. }
  1566. el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
  1567. }
  1568. return null;
  1569. },
  1570. // Introduced in DOM Level 3:
  1571. lookupNamespaceURI:function(prefix){
  1572. var el = this;
  1573. while(el){
  1574. var map = el._nsMap;
  1575. //console.dir(map)
  1576. if(map){
  1577. if(prefix in map){
  1578. return map[prefix] ;
  1579. }
  1580. }
  1581. el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
  1582. }
  1583. return null;
  1584. },
  1585. // Introduced in DOM Level 3:
  1586. isDefaultNamespace:function(namespaceURI){
  1587. var prefix = this.lookupPrefix(namespaceURI);
  1588. return prefix == null;
  1589. }
  1590. };
  1591. function _xmlEncoder(c){
  1592. return c == '<' && '&lt;' ||
  1593. c == '>' && '&gt;' ||
  1594. c == '&' && '&amp;' ||
  1595. c == '"' && '&quot;' ||
  1596. '&#'+c.charCodeAt()+';'
  1597. }
  1598. copy(NodeType,Node);
  1599. copy(NodeType,Node.prototype);
  1600. /**
  1601. * @param callback return true for continue,false for break
  1602. * @return boolean true: break visit;
  1603. */
  1604. function _visitNode(node,callback){
  1605. if(callback(node)){
  1606. return true;
  1607. }
  1608. if(node = node.firstChild){
  1609. do{
  1610. if(_visitNode(node,callback)){return true}
  1611. }while(node=node.nextSibling)
  1612. }
  1613. }
  1614. function Document(){
  1615. }
  1616. function _onAddAttribute(doc,el,newAttr){
  1617. doc && doc._inc++;
  1618. var ns = newAttr.namespaceURI ;
  1619. if(ns === NAMESPACE.XMLNS){
  1620. //update namespace
  1621. el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value
  1622. }
  1623. }
  1624. function _onRemoveAttribute(doc,el,newAttr,remove){
  1625. doc && doc._inc++;
  1626. var ns = newAttr.namespaceURI ;
  1627. if(ns === NAMESPACE.XMLNS){
  1628. //update namespace
  1629. delete el._nsMap[newAttr.prefix?newAttr.localName:'']
  1630. }
  1631. }
  1632. /**
  1633. * Updates `el.childNodes`, updating the indexed items and it's `length`.
  1634. * Passing `newChild` means it will be appended.
  1635. * Otherwise it's assumed that an item has been removed,
  1636. * and `el.firstNode` and it's `.nextSibling` are used
  1637. * to walk the current list of child nodes.
  1638. *
  1639. * @param {Document} doc
  1640. * @param {Node} el
  1641. * @param {Node} [newChild]
  1642. * @private
  1643. */
  1644. function _onUpdateChild (doc, el, newChild) {
  1645. if(doc && doc._inc){
  1646. doc._inc++;
  1647. //update childNodes
  1648. var cs = el.childNodes;
  1649. if (newChild) {
  1650. cs[cs.length++] = newChild;
  1651. } else {
  1652. var child = el.firstChild;
  1653. var i = 0;
  1654. while (child) {
  1655. cs[i++] = child;
  1656. child = child.nextSibling;
  1657. }
  1658. cs.length = i;
  1659. delete cs[cs.length];
  1660. }
  1661. }
  1662. }
  1663. /**
  1664. * Removes the connections between `parentNode` and `child`
  1665. * and any existing `child.previousSibling` or `child.nextSibling`.
  1666. *
  1667. * @see https://github.com/xmldom/xmldom/issues/135
  1668. * @see https://github.com/xmldom/xmldom/issues/145
  1669. *
  1670. * @param {Node} parentNode
  1671. * @param {Node} child
  1672. * @returns {Node} the child that was removed.
  1673. * @private
  1674. */
  1675. function _removeChild (parentNode, child) {
  1676. var previous = child.previousSibling;
  1677. var next = child.nextSibling;
  1678. if (previous) {
  1679. previous.nextSibling = next;
  1680. } else {
  1681. parentNode.firstChild = next;
  1682. }
  1683. if (next) {
  1684. next.previousSibling = previous;
  1685. } else {
  1686. parentNode.lastChild = previous;
  1687. }
  1688. child.parentNode = null;
  1689. child.previousSibling = null;
  1690. child.nextSibling = null;
  1691. _onUpdateChild(parentNode.ownerDocument, parentNode);
  1692. return child;
  1693. }
  1694. /**
  1695. * preformance key(refChild == null)
  1696. */
  1697. function _insertBefore(parentNode,newChild,nextChild){
  1698. var cp = newChild.parentNode;
  1699. if(cp){
  1700. cp.removeChild(newChild);//remove and update
  1701. }
  1702. if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
  1703. var newFirst = newChild.firstChild;
  1704. if (newFirst == null) {
  1705. return newChild;
  1706. }
  1707. var newLast = newChild.lastChild;
  1708. }else{
  1709. newFirst = newLast = newChild;
  1710. }
  1711. var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
  1712. newFirst.previousSibling = pre;
  1713. newLast.nextSibling = nextChild;
  1714. if(pre){
  1715. pre.nextSibling = newFirst;
  1716. }else{
  1717. parentNode.firstChild = newFirst;
  1718. }
  1719. if(nextChild == null){
  1720. parentNode.lastChild = newLast;
  1721. }else{
  1722. nextChild.previousSibling = newLast;
  1723. }
  1724. do{
  1725. newFirst.parentNode = parentNode;
  1726. }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
  1727. _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
  1728. //console.log(parentNode.lastChild.nextSibling == null)
  1729. if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
  1730. newChild.firstChild = newChild.lastChild = null;
  1731. }
  1732. return newChild;
  1733. }
  1734. /**
  1735. * Appends `newChild` to `parentNode`.
  1736. * If `newChild` is already connected to a `parentNode` it is first removed from it.
  1737. *
  1738. * @see https://github.com/xmldom/xmldom/issues/135
  1739. * @see https://github.com/xmldom/xmldom/issues/145
  1740. * @param {Node} parentNode
  1741. * @param {Node} newChild
  1742. * @returns {Node}
  1743. * @private
  1744. */
  1745. function _appendSingleChild (parentNode, newChild) {
  1746. if (newChild.parentNode) {
  1747. newChild.parentNode.removeChild(newChild);
  1748. }
  1749. newChild.parentNode = parentNode;
  1750. newChild.previousSibling = parentNode.lastChild;
  1751. newChild.nextSibling = null;
  1752. if (newChild.previousSibling) {
  1753. newChild.previousSibling.nextSibling = newChild;
  1754. } else {
  1755. parentNode.firstChild = newChild;
  1756. }
  1757. parentNode.lastChild = newChild;
  1758. _onUpdateChild(parentNode.ownerDocument, parentNode, newChild);
  1759. return newChild;
  1760. }
  1761. Document.prototype = {
  1762. //implementation : null,
  1763. nodeName : '#document',
  1764. nodeType : DOCUMENT_NODE,
  1765. /**
  1766. * The DocumentType node of the document.
  1767. *
  1768. * @readonly
  1769. * @type DocumentType
  1770. */
  1771. doctype : null,
  1772. documentElement : null,
  1773. _inc : 1,
  1774. insertBefore : function(newChild, refChild){//raises
  1775. if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
  1776. var child = newChild.firstChild;
  1777. while(child){
  1778. var next = child.nextSibling;
  1779. this.insertBefore(child,refChild);
  1780. child = next;
  1781. }
  1782. return newChild;
  1783. }
  1784. if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
  1785. this.documentElement = newChild;
  1786. }
  1787. return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
  1788. },
  1789. removeChild : function(oldChild){
  1790. if(this.documentElement == oldChild){
  1791. this.documentElement = null;
  1792. }
  1793. return _removeChild(this,oldChild);
  1794. },
  1795. // Introduced in DOM Level 2:
  1796. importNode : function(importedNode,deep){
  1797. return importNode(this,importedNode,deep);
  1798. },
  1799. // Introduced in DOM Level 2:
  1800. getElementById : function(id){
  1801. var rtv = null;
  1802. _visitNode(this.documentElement,function(node){
  1803. if(node.nodeType == ELEMENT_NODE){
  1804. if(node.getAttribute('id') == id){
  1805. rtv = node;
  1806. return true;
  1807. }
  1808. }
  1809. })
  1810. return rtv;
  1811. },
  1812. /**
  1813. * The `getElementsByClassName` method of `Document` interface returns an array-like object
  1814. * of all child elements which have **all** of the given class name(s).
  1815. *
  1816. * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters.
  1817. *
  1818. *
  1819. * Warning: This is a live LiveNodeList.
  1820. * Changes in the DOM will reflect in the array as the changes occur.
  1821. * If an element selected by this array no longer qualifies for the selector,
  1822. * it will automatically be removed. Be aware of this for iteration purposes.
  1823. *
  1824. * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace
  1825. *
  1826. * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
  1827. * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
  1828. */
  1829. getElementsByClassName: function(classNames) {
  1830. var classNamesSet = toOrderedSet(classNames)
  1831. return new LiveNodeList(this, function(base) {
  1832. var ls = [];
  1833. if (classNamesSet.length > 0) {
  1834. _visitNode(base.documentElement, function(node) {
  1835. if(node !== base && node.nodeType === ELEMENT_NODE) {
  1836. var nodeClassNames = node.getAttribute('class')
  1837. // can be null if the attribute does not exist
  1838. if (nodeClassNames) {
  1839. // before splitting and iterating just compare them for the most common case
  1840. var matches = classNames === nodeClassNames;
  1841. if (!matches) {
  1842. var nodeClassNamesSet = toOrderedSet(nodeClassNames)
  1843. matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet))
  1844. }
  1845. if(matches) {
  1846. ls.push(node);
  1847. }
  1848. }
  1849. }
  1850. });
  1851. }
  1852. return ls;
  1853. });
  1854. },
  1855. //document factory method:
  1856. createElement : function(tagName){
  1857. var node = new Element();
  1858. node.ownerDocument = this;
  1859. node.nodeName = tagName;
  1860. node.tagName = tagName;
  1861. node.localName = tagName;
  1862. node.childNodes = new NodeList();
  1863. var attrs = node.attributes = new NamedNodeMap();
  1864. attrs._ownerElement = node;
  1865. return node;
  1866. },
  1867. createDocumentFragment : function(){
  1868. var node = new DocumentFragment();
  1869. node.ownerDocument = this;
  1870. node.childNodes = new NodeList();
  1871. return node;
  1872. },
  1873. createTextNode : function(data){
  1874. var node = new Text();
  1875. node.ownerDocument = this;
  1876. node.appendData(data)
  1877. return node;
  1878. },
  1879. createComment : function(data){
  1880. var node = new Comment();
  1881. node.ownerDocument = this;
  1882. node.appendData(data)
  1883. return node;
  1884. },
  1885. createCDATASection : function(data){
  1886. var node = new CDATASection();
  1887. node.ownerDocument = this;
  1888. node.appendData(data)
  1889. return node;
  1890. },
  1891. createProcessingInstruction : function(target,data){
  1892. var node = new ProcessingInstruction();
  1893. node.ownerDocument = this;
  1894. node.tagName = node.target = target;
  1895. node.nodeValue= node.data = data;
  1896. return node;
  1897. },
  1898. createAttribute : function(name){
  1899. var node = new Attr();
  1900. node.ownerDocument = this;
  1901. node.name = name;
  1902. node.nodeName = name;
  1903. node.localName = name;
  1904. node.specified = true;
  1905. return node;
  1906. },
  1907. createEntityReference : function(name){
  1908. var node = new EntityReference();
  1909. node.ownerDocument = this;
  1910. node.nodeName = name;
  1911. return node;
  1912. },
  1913. // Introduced in DOM Level 2:
  1914. createElementNS : function(namespaceURI,qualifiedName){
  1915. var node = new Element();
  1916. var pl = qualifiedName.split(':');
  1917. var attrs = node.attributes = new NamedNodeMap();
  1918. node.childNodes = new NodeList();
  1919. node.ownerDocument = this;
  1920. node.nodeName = qualifiedName;
  1921. node.tagName = qualifiedName;
  1922. node.namespaceURI = namespaceURI;
  1923. if(pl.length == 2){
  1924. node.prefix = pl[0];
  1925. node.localName = pl[1];
  1926. }else{
  1927. //el.prefix = null;
  1928. node.localName = qualifiedName;
  1929. }
  1930. attrs._ownerElement = node;
  1931. return node;
  1932. },
  1933. // Introduced in DOM Level 2:
  1934. createAttributeNS : function(namespaceURI,qualifiedName){
  1935. var node = new Attr();
  1936. var pl = qualifiedName.split(':');
  1937. node.ownerDocument = this;
  1938. node.nodeName = qualifiedName;
  1939. node.name = qualifiedName;
  1940. node.namespaceURI = namespaceURI;
  1941. node.specified = true;
  1942. if(pl.length == 2){
  1943. node.prefix = pl[0];
  1944. node.localName = pl[1];
  1945. }else{
  1946. //el.prefix = null;
  1947. node.localName = qualifiedName;
  1948. }
  1949. return node;
  1950. }
  1951. };
  1952. _extends(Document,Node);
  1953. function Element() {
  1954. this._nsMap = {};
  1955. };
  1956. Element.prototype = {
  1957. nodeType : ELEMENT_NODE,
  1958. hasAttribute : function(name){
  1959. return this.getAttributeNode(name)!=null;
  1960. },
  1961. getAttribute : function(name){
  1962. var attr = this.getAttributeNode(name);
  1963. return attr && attr.value || '';
  1964. },
  1965. getAttributeNode : function(name){
  1966. return this.attributes.getNamedItem(name);
  1967. },
  1968. setAttribute : function(name, value){
  1969. var attr = this.ownerDocument.createAttribute(name);
  1970. attr.value = attr.nodeValue = "" + value;
  1971. this.setAttributeNode(attr)
  1972. },
  1973. removeAttribute : function(name){
  1974. var attr = this.getAttributeNode(name)
  1975. attr && this.removeAttributeNode(attr);
  1976. },
  1977. //four real opeartion method
  1978. appendChild:function(newChild){
  1979. if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
  1980. return this.insertBefore(newChild,null);
  1981. }else{
  1982. return _appendSingleChild(this,newChild);
  1983. }
  1984. },
  1985. setAttributeNode : function(newAttr){
  1986. return this.attributes.setNamedItem(newAttr);
  1987. },
  1988. setAttributeNodeNS : function(newAttr){
  1989. return this.attributes.setNamedItemNS(newAttr);
  1990. },
  1991. removeAttributeNode : function(oldAttr){
  1992. //console.log(this == oldAttr.ownerElement)
  1993. return this.attributes.removeNamedItem(oldAttr.nodeName);
  1994. },
  1995. //get real attribute name,and remove it by removeAttributeNode
  1996. removeAttributeNS : function(namespaceURI, localName){
  1997. var old = this.getAttributeNodeNS(namespaceURI, localName);
  1998. old && this.removeAttributeNode(old);
  1999. },
  2000. hasAttributeNS : function(namespaceURI, localName){
  2001. return this.getAttributeNodeNS(namespaceURI, localName)!=null;
  2002. },
  2003. getAttributeNS : function(namespaceURI, localName){
  2004. var attr = this.getAttributeNodeNS(namespaceURI, localName);
  2005. return attr && attr.value || '';
  2006. },
  2007. setAttributeNS : function(namespaceURI, qualifiedName, value){
  2008. var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
  2009. attr.value = attr.nodeValue = "" + value;
  2010. this.setAttributeNode(attr)
  2011. },
  2012. getAttributeNodeNS : function(namespaceURI, localName){
  2013. return this.attributes.getNamedItemNS(namespaceURI, localName);
  2014. },
  2015. getElementsByTagName : function(tagName){
  2016. return new LiveNodeList(this,function(base){
  2017. var ls = [];
  2018. _visitNode(base,function(node){
  2019. if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
  2020. ls.push(node);
  2021. }
  2022. });
  2023. return ls;
  2024. });
  2025. },
  2026. getElementsByTagNameNS : function(namespaceURI, localName){
  2027. return new LiveNodeList(this,function(base){
  2028. var ls = [];
  2029. _visitNode(base,function(node){
  2030. if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
  2031. ls.push(node);
  2032. }
  2033. });
  2034. return ls;
  2035. });
  2036. }
  2037. };
  2038. Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
  2039. Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
  2040. _extends(Element,Node);
  2041. function Attr() {
  2042. };
  2043. Attr.prototype.nodeType = ATTRIBUTE_NODE;
  2044. _extends(Attr,Node);
  2045. function CharacterData() {
  2046. };
  2047. CharacterData.prototype = {
  2048. data : '',
  2049. substringData : function(offset, count) {
  2050. return this.data.substring(offset, offset+count);
  2051. },
  2052. appendData: function(text) {
  2053. text = this.data+text;
  2054. this.nodeValue = this.data = text;
  2055. this.length = text.length;
  2056. },
  2057. insertData: function(offset,text) {
  2058. this.replaceData(offset,0,text);
  2059. },
  2060. appendChild:function(newChild){
  2061. throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
  2062. },
  2063. deleteData: function(offset, count) {
  2064. this.replaceData(offset,count,"");
  2065. },
  2066. replaceData: function(offset, count, text) {
  2067. var start = this.data.substring(0,offset);
  2068. var end = this.data.substring(offset+count);
  2069. text = start + text + end;
  2070. this.nodeValue = this.data = text;
  2071. this.length = text.length;
  2072. }
  2073. }
  2074. _extends(CharacterData,Node);
  2075. function Text() {
  2076. };
  2077. Text.prototype = {
  2078. nodeName : "#text",
  2079. nodeType : TEXT_NODE,
  2080. splitText : function(offset) {
  2081. var text = this.data;
  2082. var newText = text.substring(offset);
  2083. text = text.substring(0, offset);
  2084. this.data = this.nodeValue = text;
  2085. this.length = text.length;
  2086. var newNode = this.ownerDocument.createTextNode(newText);
  2087. if(this.parentNode){
  2088. this.parentNode.insertBefore(newNode, this.nextSibling);
  2089. }
  2090. return newNode;
  2091. }
  2092. }
  2093. _extends(Text,CharacterData);
  2094. function Comment() {
  2095. };
  2096. Comment.prototype = {
  2097. nodeName : "#comment",
  2098. nodeType : COMMENT_NODE
  2099. }
  2100. _extends(Comment,CharacterData);
  2101. function CDATASection() {
  2102. };
  2103. CDATASection.prototype = {
  2104. nodeName : "#cdata-section",
  2105. nodeType : CDATA_SECTION_NODE
  2106. }
  2107. _extends(CDATASection,CharacterData);
  2108. function DocumentType() {
  2109. };
  2110. DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
  2111. _extends(DocumentType,Node);
  2112. function Notation() {
  2113. };
  2114. Notation.prototype.nodeType = NOTATION_NODE;
  2115. _extends(Notation,Node);
  2116. function Entity() {
  2117. };
  2118. Entity.prototype.nodeType = ENTITY_NODE;
  2119. _extends(Entity,Node);
  2120. function EntityReference() {
  2121. };
  2122. EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
  2123. _extends(EntityReference,Node);
  2124. function DocumentFragment() {
  2125. };
  2126. DocumentFragment.prototype.nodeName = "#document-fragment";
  2127. DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
  2128. _extends(DocumentFragment,Node);
  2129. function ProcessingInstruction() {
  2130. }
  2131. ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
  2132. _extends(ProcessingInstruction,Node);
  2133. function XMLSerializer(){}
  2134. XMLSerializer.prototype.serializeToString = function(node,isHtml,nodeFilter){
  2135. return nodeSerializeToString.call(node,isHtml,nodeFilter);
  2136. }
  2137. Node.prototype.toString = nodeSerializeToString;
  2138. function nodeSerializeToString(isHtml,nodeFilter){
  2139. var buf = [];
  2140. var refNode = this.nodeType == 9 && this.documentElement || this;
  2141. var prefix = refNode.prefix;
  2142. var uri = refNode.namespaceURI;
  2143. if(uri && prefix == null){
  2144. //console.log(prefix)
  2145. var prefix = refNode.lookupPrefix(uri);
  2146. if(prefix == null){
  2147. //isHTML = true;
  2148. var visibleNamespaces=[
  2149. {namespace:uri,prefix:null}
  2150. //{namespace:uri,prefix:''}
  2151. ]
  2152. }
  2153. }
  2154. serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
  2155. //console.log('###',this.nodeType,uri,prefix,buf.join(''))
  2156. return buf.join('');
  2157. }
  2158. function needNamespaceDefine(node, isHTML, visibleNamespaces) {
  2159. var prefix = node.prefix || '';
  2160. var uri = node.namespaceURI;
  2161. // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) ,
  2162. // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl :
  2163. // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty.
  2164. // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using)
  2165. // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared :
  2166. // > [...] Furthermore, the attribute value [...] must not be an empty string.
  2167. // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document.
  2168. if (!uri) {
  2169. return false;
  2170. }
  2171. if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) {
  2172. return false;
  2173. }
  2174. var i = visibleNamespaces.length
  2175. while (i--) {
  2176. var ns = visibleNamespaces[i];
  2177. // get namespace prefix
  2178. if (ns.prefix === prefix) {
  2179. return ns.namespace !== uri;
  2180. }
  2181. }
  2182. return true;
  2183. }
  2184. /**
  2185. * Well-formed constraint: No < in Attribute Values
  2186. * > The replacement text of any entity referred to directly or indirectly
  2187. * > in an attribute value must not contain a <.
  2188. * @see https://www.w3.org/TR/xml11/#CleanAttrVals
  2189. * @see https://www.w3.org/TR/xml11/#NT-AttValue
  2190. *
  2191. * Literal whitespace other than space that appear in attribute values
  2192. * are serialized as their entity references, so they will be preserved.
  2193. * (In contrast to whitespace literals in the input which are normalized to spaces)
  2194. * @see https://www.w3.org/TR/xml11/#AVNormalize
  2195. * @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes
  2196. */
  2197. function addSerializedAttribute(buf, qualifiedName, value) {
  2198. buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"')
  2199. }
  2200. function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
  2201. if (!visibleNamespaces) {
  2202. visibleNamespaces = [];
  2203. }
  2204. if(nodeFilter){
  2205. node = nodeFilter(node);
  2206. if(node){
  2207. if(typeof node == 'string'){
  2208. buf.push(node);
  2209. return;
  2210. }
  2211. }else{
  2212. return;
  2213. }
  2214. //buf.sort.apply(attrs, attributeSorter);
  2215. }
  2216. switch(node.nodeType){
  2217. case ELEMENT_NODE:
  2218. var attrs = node.attributes;
  2219. var len = attrs.length;
  2220. var child = node.firstChild;
  2221. var nodeName = node.tagName;
  2222. isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML
  2223. var prefixedNodeName = nodeName
  2224. if (!isHTML && !node.prefix && node.namespaceURI) {
  2225. var defaultNS
  2226. // lookup current default ns from `xmlns` attribute
  2227. for (var ai = 0; ai < attrs.length; ai++) {
  2228. if (attrs.item(ai).name === 'xmlns') {
  2229. defaultNS = attrs.item(ai).value
  2230. break
  2231. }
  2232. }
  2233. if (!defaultNS) {
  2234. // lookup current default ns in visibleNamespaces
  2235. for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
  2236. var namespace = visibleNamespaces[nsi]
  2237. if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) {
  2238. defaultNS = namespace.namespace
  2239. break
  2240. }
  2241. }
  2242. }
  2243. if (defaultNS !== node.namespaceURI) {
  2244. for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
  2245. var namespace = visibleNamespaces[nsi]
  2246. if (namespace.namespace === node.namespaceURI) {
  2247. if (namespace.prefix) {
  2248. prefixedNodeName = namespace.prefix + ':' + nodeName
  2249. }
  2250. break
  2251. }
  2252. }
  2253. }
  2254. }
  2255. buf.push('<', prefixedNodeName);
  2256. for(var i=0;i<len;i++){
  2257. // add namespaces for attributes
  2258. var attr = attrs.item(i);
  2259. if (attr.prefix == 'xmlns') {
  2260. visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
  2261. }else if(attr.nodeName == 'xmlns'){
  2262. visibleNamespaces.push({ prefix: '', namespace: attr.value });
  2263. }
  2264. }
  2265. for(var i=0;i<len;i++){
  2266. var attr = attrs.item(i);
  2267. if (needNamespaceDefine(attr,isHTML, visibleNamespaces)) {
  2268. var prefix = attr.prefix||'';
  2269. var uri = attr.namespaceURI;
  2270. addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
  2271. visibleNamespaces.push({ prefix: prefix, namespace:uri });
  2272. }
  2273. serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
  2274. }
  2275. // add namespace for current node
  2276. if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) {
  2277. var prefix = node.prefix||'';
  2278. var uri = node.namespaceURI;
  2279. addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
  2280. visibleNamespaces.push({ prefix: prefix, namespace:uri });
  2281. }
  2282. if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
  2283. buf.push('>');
  2284. //if is cdata child node
  2285. if(isHTML && /^script$/i.test(nodeName)){
  2286. while(child){
  2287. if(child.data){
  2288. buf.push(child.data);
  2289. }else{
  2290. serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
  2291. }
  2292. child = child.nextSibling;
  2293. }
  2294. }else
  2295. {
  2296. while(child){
  2297. serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
  2298. child = child.nextSibling;
  2299. }
  2300. }
  2301. buf.push('</',prefixedNodeName,'>');
  2302. }else{
  2303. buf.push('/>');
  2304. }
  2305. // remove added visible namespaces
  2306. //visibleNamespaces.length = startVisibleNamespaces;
  2307. return;
  2308. case DOCUMENT_NODE:
  2309. case DOCUMENT_FRAGMENT_NODE:
  2310. var child = node.firstChild;
  2311. while(child){
  2312. serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
  2313. child = child.nextSibling;
  2314. }
  2315. return;
  2316. case ATTRIBUTE_NODE:
  2317. return addSerializedAttribute(buf, node.name, node.value);
  2318. case TEXT_NODE:
  2319. /**
  2320. * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
  2321. * except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section.
  2322. * If they are needed elsewhere, they must be escaped using either numeric character references or the strings
  2323. * `&amp;` and `&lt;` respectively.
  2324. * The right angle bracket (>) may be represented using the string " &gt; ", and must, for compatibility,
  2325. * be escaped using either `&gt;` or a character reference when it appears in the string `]]>` in content,
  2326. * when that string is not marking the end of a CDATA section.
  2327. *
  2328. * In the content of elements, character data is any string of characters
  2329. * which does not contain the start-delimiter of any markup
  2330. * and does not include the CDATA-section-close delimiter, `]]>`.
  2331. *
  2332. * @see https://www.w3.org/TR/xml/#NT-CharData
  2333. * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node
  2334. */
  2335. return buf.push(node.data
  2336. .replace(/[<&>]/g,_xmlEncoder)
  2337. );
  2338. case CDATA_SECTION_NODE:
  2339. return buf.push( '<![CDATA[',node.data,']]>');
  2340. case COMMENT_NODE:
  2341. return buf.push( "<!--",node.data,"-->");
  2342. case DOCUMENT_TYPE_NODE:
  2343. var pubid = node.publicId;
  2344. var sysid = node.systemId;
  2345. buf.push('<!DOCTYPE ',node.name);
  2346. if(pubid){
  2347. buf.push(' PUBLIC ', pubid);
  2348. if (sysid && sysid!='.') {
  2349. buf.push(' ', sysid);
  2350. }
  2351. buf.push('>');
  2352. }else if(sysid && sysid!='.'){
  2353. buf.push(' SYSTEM ', sysid, '>');
  2354. }else{
  2355. var sub = node.internalSubset;
  2356. if(sub){
  2357. buf.push(" [",sub,"]");
  2358. }
  2359. buf.push(">");
  2360. }
  2361. return;
  2362. case PROCESSING_INSTRUCTION_NODE:
  2363. return buf.push( "<?",node.target," ",node.data,"?>");
  2364. case ENTITY_REFERENCE_NODE:
  2365. return buf.push( '&',node.nodeName,';');
  2366. //case ENTITY_NODE:
  2367. //case NOTATION_NODE:
  2368. default:
  2369. buf.push('??',node.nodeName);
  2370. }
  2371. }
  2372. function importNode(doc,node,deep){
  2373. var node2;
  2374. switch (node.nodeType) {
  2375. case ELEMENT_NODE:
  2376. node2 = node.cloneNode(false);
  2377. node2.ownerDocument = doc;
  2378. //var attrs = node2.attributes;
  2379. //var len = attrs.length;
  2380. //for(var i=0;i<len;i++){
  2381. //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
  2382. //}
  2383. case DOCUMENT_FRAGMENT_NODE:
  2384. break;
  2385. case ATTRIBUTE_NODE:
  2386. deep = true;
  2387. break;
  2388. //case ENTITY_REFERENCE_NODE:
  2389. //case PROCESSING_INSTRUCTION_NODE:
  2390. ////case TEXT_NODE:
  2391. //case CDATA_SECTION_NODE:
  2392. //case COMMENT_NODE:
  2393. // deep = false;
  2394. // break;
  2395. //case DOCUMENT_NODE:
  2396. //case DOCUMENT_TYPE_NODE:
  2397. //cannot be imported.
  2398. //case ENTITY_NODE:
  2399. //case NOTATION_NODE:
  2400. //can not hit in level3
  2401. //default:throw e;
  2402. }
  2403. if(!node2){
  2404. node2 = node.cloneNode(false);//false
  2405. }
  2406. node2.ownerDocument = doc;
  2407. node2.parentNode = null;
  2408. if(deep){
  2409. var child = node.firstChild;
  2410. while(child){
  2411. node2.appendChild(importNode(doc,child,deep));
  2412. child = child.nextSibling;
  2413. }
  2414. }
  2415. return node2;
  2416. }
  2417. //
  2418. //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
  2419. // attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
  2420. function cloneNode(doc,node,deep){
  2421. var node2 = new node.constructor();
  2422. for(var n in node){
  2423. var v = node[n];
  2424. if(typeof v != 'object' ){
  2425. if(v != node2[n]){
  2426. node2[n] = v;
  2427. }
  2428. }
  2429. }
  2430. if(node.childNodes){
  2431. node2.childNodes = new NodeList();
  2432. }
  2433. node2.ownerDocument = doc;
  2434. switch (node2.nodeType) {
  2435. case ELEMENT_NODE:
  2436. var attrs = node.attributes;
  2437. var attrs2 = node2.attributes = new NamedNodeMap();
  2438. var len = attrs.length
  2439. attrs2._ownerElement = node2;
  2440. for(var i=0;i<len;i++){
  2441. node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
  2442. }
  2443. break;;
  2444. case ATTRIBUTE_NODE:
  2445. deep = true;
  2446. }
  2447. if(deep){
  2448. var child = node.firstChild;
  2449. while(child){
  2450. node2.appendChild(cloneNode(doc,child,deep));
  2451. child = child.nextSibling;
  2452. }
  2453. }
  2454. return node2;
  2455. }
  2456. function __set__(object,key,value){
  2457. object[key] = value
  2458. }
  2459. //do dynamic
  2460. try{
  2461. if(Object.defineProperty){
  2462. Object.defineProperty(LiveNodeList.prototype,'length',{
  2463. get:function(){
  2464. _updateLiveList(this);
  2465. return this.$$length;
  2466. }
  2467. });
  2468. Object.defineProperty(Node.prototype,'textContent',{
  2469. get:function(){
  2470. return getTextContent(this);
  2471. },
  2472. set:function(data){
  2473. switch(this.nodeType){
  2474. case ELEMENT_NODE:
  2475. case DOCUMENT_FRAGMENT_NODE:
  2476. while(this.firstChild){
  2477. this.removeChild(this.firstChild);
  2478. }
  2479. if(data || String(data)){
  2480. this.appendChild(this.ownerDocument.createTextNode(data));
  2481. }
  2482. break;
  2483. default:
  2484. this.data = data;
  2485. this.value = data;
  2486. this.nodeValue = data;
  2487. }
  2488. }
  2489. })
  2490. function getTextContent(node){
  2491. switch(node.nodeType){
  2492. case ELEMENT_NODE:
  2493. case DOCUMENT_FRAGMENT_NODE:
  2494. var buf = [];
  2495. node = node.firstChild;
  2496. while(node){
  2497. if(node.nodeType!==7 && node.nodeType !==8){
  2498. buf.push(getTextContent(node));
  2499. }
  2500. node = node.nextSibling;
  2501. }
  2502. return buf.join('');
  2503. default:
  2504. return node.nodeValue;
  2505. }
  2506. }
  2507. __set__ = function(object,key,value){
  2508. //console.log(value)
  2509. object['$$'+key] = value
  2510. }
  2511. }
  2512. }catch(e){//ie8
  2513. }
  2514. //if(typeof require == 'function'){
  2515. exports.DocumentType = DocumentType;
  2516. exports.DOMException = DOMException;
  2517. exports.DOMImplementation = DOMImplementation;
  2518. exports.Element = Element;
  2519. exports.Node = Node;
  2520. exports.NodeList = NodeList;
  2521. exports.XMLSerializer = XMLSerializer;
  2522. //}
  2523. /***/ }),
  2524. /* 4 */
  2525. /***/ (function(module, exports) {
  2526. var initEvent = function (cos) {
  2527. var listeners = {};
  2528. var getList = function (action) {
  2529. !listeners[action] && (listeners[action] = []);
  2530. return listeners[action];
  2531. };
  2532. cos.on = function (action, callback) {
  2533. if (action === 'task-list-update') {
  2534. console.warn('warning: Event "' + action + '" has been deprecated. Please use "list-update" instead.');
  2535. }
  2536. getList(action).push(callback);
  2537. };
  2538. cos.off = function (action, callback) {
  2539. var list = getList(action);
  2540. for (var i = list.length - 1; i >= 0; i--) {
  2541. callback === list[i] && list.splice(i, 1);
  2542. }
  2543. };
  2544. cos.emit = function (action, data) {
  2545. var list = getList(action).map(function (cb) {
  2546. return cb;
  2547. });
  2548. for (var i = 0; i < list.length; i++) {
  2549. list[i](data);
  2550. }
  2551. };
  2552. };
  2553. var EventProxy = function () {
  2554. initEvent(this);
  2555. };
  2556. module.exports.init = initEvent;
  2557. module.exports.EventProxy = EventProxy;
  2558. /***/ }),
  2559. /* 5 */
  2560. /***/ (function(module, exports, __webpack_require__) {
  2561. var util = __webpack_require__(0);
  2562. // 按照文件特征值,缓存 UploadId
  2563. var cacheKey = 'cos_sdk_upload_cache';
  2564. var expires = 30 * 24 * 3600;
  2565. var cache;
  2566. var timer;
  2567. var getCache = function () {
  2568. try {
  2569. var val = JSON.parse(localStorage.getItem(cacheKey));
  2570. } catch (e) {}
  2571. if (!val) val = [];
  2572. cache = val;
  2573. };
  2574. var setCache = function () {
  2575. try {
  2576. localStorage.setItem(cacheKey, JSON.stringify(cache));
  2577. } catch (e) {}
  2578. };
  2579. var init = function () {
  2580. if (cache) return;
  2581. getCache.call(this);
  2582. // 清理太老旧的数据
  2583. var changed = false;
  2584. var now = Math.round(Date.now() / 1000);
  2585. for (var i = cache.length - 1; i >= 0; i--) {
  2586. var mtime = cache[i][2];
  2587. if (!mtime || mtime + expires < now) {
  2588. cache.splice(i, 1);
  2589. changed = true;
  2590. }
  2591. }
  2592. changed && setCache();
  2593. };
  2594. // 把缓存存到本地
  2595. var save = function () {
  2596. if (timer) return;
  2597. timer = setTimeout(function () {
  2598. setCache();
  2599. timer = null;
  2600. }, 400);
  2601. };
  2602. var mod = {
  2603. using: {},
  2604. // 标记 UploadId 正在使用
  2605. setUsing: function (uuid) {
  2606. mod.using[uuid] = true;
  2607. },
  2608. // 标记 UploadId 已经没在使用
  2609. removeUsing: function (uuid) {
  2610. delete mod.using[uuid];
  2611. },
  2612. // 用上传参数生成哈希值
  2613. getFileId: function (file, ChunkSize, Bucket, Key) {
  2614. if (file.name && file.size && file.lastModifiedDate && ChunkSize) {
  2615. return util.md5([file.name, file.size, file.lastModifiedDate, ChunkSize, Bucket, Key].join('::'));
  2616. } else {
  2617. return null;
  2618. }
  2619. },
  2620. // 获取文件对应的 UploadId 列表
  2621. getUploadIdList: function (uuid) {
  2622. if (!uuid) return null;
  2623. init.call(this);
  2624. var list = [];
  2625. for (var i = 0; i < cache.length; i++) {
  2626. if (cache[i][0] === uuid) list.push(cache[i][1]);
  2627. }
  2628. return list.length ? list : null;
  2629. },
  2630. // 缓存 UploadId
  2631. saveUploadId: function (uuid, UploadId, limit) {
  2632. init.call(this);
  2633. if (!uuid) return;
  2634. // 清理没用的 UploadId,js 文件没有 FilePath ,只清理相同记录
  2635. for (var i = cache.length - 1; i >= 0; i--) {
  2636. var item = cache[i];
  2637. if (item[0] === uuid && item[1] === UploadId) {
  2638. cache.splice(i, 1);
  2639. }
  2640. }
  2641. cache.unshift([uuid, UploadId, Math.round(Date.now() / 1000)]);
  2642. if (cache.length > limit) cache.splice(limit);
  2643. save();
  2644. },
  2645. // UploadId 已用完,移除掉
  2646. removeUploadId: function (UploadId) {
  2647. init.call(this);
  2648. delete mod.using[UploadId];
  2649. for (var i = cache.length - 1; i >= 0; i--) {
  2650. if (cache[i][1] === UploadId) cache.splice(i, 1);
  2651. }
  2652. save();
  2653. }
  2654. };
  2655. module.exports = mod;
  2656. /***/ }),
  2657. /* 6 */
  2658. /***/ (function(module, exports, __webpack_require__) {
  2659. var COS = __webpack_require__(7);
  2660. module.exports = COS;
  2661. /***/ }),
  2662. /* 7 */
  2663. /***/ (function(module, exports, __webpack_require__) {
  2664. "use strict";
  2665. var util = __webpack_require__(0);
  2666. var event = __webpack_require__(4);
  2667. var task = __webpack_require__(18);
  2668. var base = __webpack_require__(19);
  2669. var advance = __webpack_require__(21);
  2670. var defaultOptions = {
  2671. AppId: '', // AppId 已废弃,请拼接到 Bucket 后传入,例如:test-1250000000
  2672. SecretId: '',
  2673. SecretKey: '',
  2674. SecurityToken: '', // 使用临时密钥需要注意自行刷新 Token
  2675. ChunkRetryTimes: 2,
  2676. FileParallelLimit: 3,
  2677. ChunkParallelLimit: 3,
  2678. ChunkSize: 1024 * 1024,
  2679. SliceSize: 1024 * 1024,
  2680. CopyChunkParallelLimit: 20,
  2681. CopyChunkSize: 1024 * 1024 * 10,
  2682. CopySliceSize: 1024 * 1024 * 10,
  2683. MaxPartNumber: 10000,
  2684. ProgressInterval: 1000,
  2685. Domain: '',
  2686. ServiceDomain: '',
  2687. Protocol: '',
  2688. CompatibilityMode: false,
  2689. ForcePathStyle: false,
  2690. UseRawKey: false,
  2691. Timeout: 0, // 单位毫秒,0 代表不设置超时时间
  2692. CorrectClockSkew: true,
  2693. SystemClockOffset: 0, // 单位毫秒,ms
  2694. UploadCheckContentMd5: false,
  2695. UploadQueueSize: 10000,
  2696. UploadAddMetaMd5: false,
  2697. UploadIdCacheLimit: 50,
  2698. UseAccelerate: false,
  2699. ForceSignHost: true // 默认将host加入签名计算,关闭后可能导致越权风险,建议保持为true
  2700. };
  2701. // 对外暴露的类
  2702. var COS = function (options) {
  2703. this.options = util.extend(util.clone(defaultOptions), options || {});
  2704. this.options.FileParallelLimit = Math.max(1, this.options.FileParallelLimit);
  2705. this.options.ChunkParallelLimit = Math.max(1, this.options.ChunkParallelLimit);
  2706. this.options.ChunkRetryTimes = Math.max(0, this.options.ChunkRetryTimes);
  2707. this.options.ChunkSize = Math.max(1024 * 1024, this.options.ChunkSize);
  2708. this.options.CopyChunkParallelLimit = Math.max(1, this.options.CopyChunkParallelLimit);
  2709. this.options.CopyChunkSize = Math.max(1024 * 1024, this.options.CopyChunkSize);
  2710. this.options.CopySliceSize = Math.max(0, this.options.CopySliceSize);
  2711. this.options.MaxPartNumber = Math.max(1024, Math.min(10000, this.options.MaxPartNumber));
  2712. this.options.Timeout = Math.max(0, this.options.Timeout);
  2713. if (this.options.AppId) {
  2714. console.warn('warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g: "test-1250000000").');
  2715. }
  2716. if (this.options.SecretId && this.options.SecretId.indexOf(' ') > -1) {
  2717. console.error('error: SecretId格式错误,请检查');
  2718. console.error('error: SecretId format is incorrect. Please check');
  2719. }
  2720. if (this.options.SecretKey && this.options.SecretKey.indexOf(' ') > -1) {
  2721. console.error('error: SecretKey格式错误,请检查');
  2722. console.error('error: SecretKey format is incorrect. Please check');
  2723. }
  2724. if (util.isNode()) {
  2725. console.warn('warning: cos-js-sdk-v5 不支持 nodejs 环境使用,请改用 cos-nodejs-sdk-v5,参考文档: https://cloud.tencent.com/document/product/436/8629');
  2726. console.warn('warning: cos-js-sdk-v5 does not support nodejs environment. Please use cos-nodejs-sdk-v5 instead. See: https://cloud.tencent.com/document/product/436/8629');
  2727. }
  2728. event.init(this);
  2729. task.init(this);
  2730. };
  2731. base.init(COS, task);
  2732. advance.init(COS, task);
  2733. COS.util = {
  2734. md5: util.md5,
  2735. xml2json: util.xml2json,
  2736. json2xml: util.json2xml
  2737. };
  2738. COS.getAuthorization = util.getAuth;
  2739. COS.version = '1.3.9';
  2740. module.exports = COS;
  2741. /***/ }),
  2742. /* 8 */
  2743. /***/ (function(module, exports, __webpack_require__) {
  2744. /* WEBPACK VAR INJECTION */(function(process, global) {var __WEBPACK_AMD_DEFINE_RESULT__;/* https://github.com/emn178/js-md5 */
  2745. (function () {
  2746. 'use strict';
  2747. var ERROR = 'input is invalid type';
  2748. var WINDOW = typeof window === 'object';
  2749. var root = WINDOW ? window : {};
  2750. if (root.JS_MD5_NO_WINDOW) {
  2751. WINDOW = false;
  2752. }
  2753. var WEB_WORKER = !WINDOW && typeof self === 'object';
  2754. var NODE_JS = !root.JS_MD5_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
  2755. if (NODE_JS) {
  2756. root = global;
  2757. } else if (WEB_WORKER) {
  2758. root = self;
  2759. }
  2760. var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports;
  2761. var AMD = "function" === 'function' && __webpack_require__(10);
  2762. var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
  2763. var HEX_CHARS = '0123456789abcdef'.split('');
  2764. var EXTRA = [128, 32768, 8388608, -2147483648];
  2765. var SHIFT = [0, 8, 16, 24];
  2766. var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];
  2767. var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
  2768. var blocks = [],
  2769. buffer8;
  2770. if (ARRAY_BUFFER) {
  2771. var buffer = new ArrayBuffer(68);
  2772. buffer8 = new Uint8Array(buffer);
  2773. blocks = new Uint32Array(buffer);
  2774. }
  2775. if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {
  2776. Array.isArray = function (obj) {
  2777. return Object.prototype.toString.call(obj) === '[object Array]';
  2778. };
  2779. }
  2780. if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
  2781. ArrayBuffer.isView = function (obj) {
  2782. return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
  2783. };
  2784. }
  2785. /**
  2786. * @method hex
  2787. * @memberof md5
  2788. * @description Output hash as hex string
  2789. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2790. * @returns {String} Hex string
  2791. * @example
  2792. * md5.hex('The quick brown fox jumps over the lazy dog');
  2793. * // equal to
  2794. * md5('The quick brown fox jumps over the lazy dog');
  2795. */
  2796. /**
  2797. * @method digest
  2798. * @memberof md5
  2799. * @description Output hash as bytes array
  2800. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2801. * @returns {Array} Bytes array
  2802. * @example
  2803. * md5.digest('The quick brown fox jumps over the lazy dog');
  2804. */
  2805. /**
  2806. * @method array
  2807. * @memberof md5
  2808. * @description Output hash as bytes array
  2809. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2810. * @returns {Array} Bytes array
  2811. * @example
  2812. * md5.array('The quick brown fox jumps over the lazy dog');
  2813. */
  2814. /**
  2815. * @method arrayBuffer
  2816. * @memberof md5
  2817. * @description Output hash as ArrayBuffer
  2818. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2819. * @returns {ArrayBuffer} ArrayBuffer
  2820. * @example
  2821. * md5.arrayBuffer('The quick brown fox jumps over the lazy dog');
  2822. */
  2823. /**
  2824. * @method buffer
  2825. * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
  2826. * @memberof md5
  2827. * @description Output hash as ArrayBuffer
  2828. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2829. * @returns {ArrayBuffer} ArrayBuffer
  2830. * @example
  2831. * md5.buffer('The quick brown fox jumps over the lazy dog');
  2832. */
  2833. /**
  2834. * @method base64
  2835. * @memberof md5
  2836. * @description Output hash as base64 string
  2837. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2838. * @returns {String} base64 string
  2839. * @example
  2840. * md5.base64('The quick brown fox jumps over the lazy dog');
  2841. */
  2842. var createOutputMethod = function (outputType) {
  2843. return function (message, isBinStr) {
  2844. return new Md5(true).update(message, isBinStr)[outputType]();
  2845. };
  2846. };
  2847. /**
  2848. * @method create
  2849. * @memberof md5
  2850. * @description Create Md5 object
  2851. * @returns {Md5} Md5 object.
  2852. * @example
  2853. * var hash = md5.create();
  2854. */
  2855. /**
  2856. * @method update
  2857. * @memberof md5
  2858. * @description Create and update Md5 object
  2859. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2860. * @returns {Md5} Md5 object.
  2861. * @example
  2862. * var hash = md5.update('The quick brown fox jumps over the lazy dog');
  2863. * // equal to
  2864. * var hash = md5.create();
  2865. * hash.update('The quick brown fox jumps over the lazy dog');
  2866. */
  2867. var createMethod = function () {
  2868. var method = createOutputMethod('hex');
  2869. if (NODE_JS) {
  2870. method = nodeWrap(method);
  2871. }
  2872. method.getCtx = method.create = function () {
  2873. return new Md5();
  2874. };
  2875. method.update = function (message) {
  2876. return method.create().update(message);
  2877. };
  2878. for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
  2879. var type = OUTPUT_TYPES[i];
  2880. method[type] = createOutputMethod(type);
  2881. }
  2882. return method;
  2883. };
  2884. var nodeWrap = function (method) {
  2885. var crypto = eval("require('crypto')");
  2886. var Buffer = eval("require('buffer').Buffer");
  2887. var nodeMethod = function (message) {
  2888. if (typeof message === 'string') {
  2889. return crypto.createHash('md5').update(message, 'utf8').digest('hex');
  2890. } else {
  2891. if (message === null || message === undefined) {
  2892. throw ERROR;
  2893. } else if (message.constructor === ArrayBuffer) {
  2894. message = new Uint8Array(message);
  2895. }
  2896. }
  2897. if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer) {
  2898. return crypto.createHash('md5').update(new Buffer(message)).digest('hex');
  2899. } else {
  2900. return method(message);
  2901. }
  2902. };
  2903. return nodeMethod;
  2904. };
  2905. /**
  2906. * Md5 class
  2907. * @class Md5
  2908. * @description This is internal class.
  2909. * @see {@link md5.create}
  2910. */
  2911. function Md5(sharedMemory) {
  2912. if (sharedMemory) {
  2913. blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
  2914. this.blocks = blocks;
  2915. this.buffer8 = buffer8;
  2916. } else {
  2917. if (ARRAY_BUFFER) {
  2918. var buffer = new ArrayBuffer(68);
  2919. this.buffer8 = new Uint8Array(buffer);
  2920. this.blocks = new Uint32Array(buffer);
  2921. } else {
  2922. this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  2923. }
  2924. }
  2925. this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;
  2926. this.finalized = this.hashed = false;
  2927. this.first = true;
  2928. }
  2929. /**
  2930. * @method update
  2931. * @memberof Md5
  2932. * @instance
  2933. * @description Update hash
  2934. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  2935. * @returns {Md5} Md5 object.
  2936. * @see {@link md5.update}
  2937. */
  2938. Md5.prototype.update = function (message, isBinStr) {
  2939. if (this.finalized) {
  2940. return;
  2941. }
  2942. var code,
  2943. index = 0,
  2944. i,
  2945. length = message.length,
  2946. blocks = this.blocks;
  2947. var buffer8 = this.buffer8;
  2948. while (index < length) {
  2949. if (this.hashed) {
  2950. this.hashed = false;
  2951. blocks[0] = blocks[16];
  2952. blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
  2953. }
  2954. if (ARRAY_BUFFER) {
  2955. for (i = this.start; index < length && i < 64; ++index) {
  2956. code = message.charCodeAt(index);
  2957. if (isBinStr || code < 0x80) {
  2958. buffer8[i++] = code;
  2959. } else if (code < 0x800) {
  2960. buffer8[i++] = 0xc0 | code >> 6;
  2961. buffer8[i++] = 0x80 | code & 0x3f;
  2962. } else if (code < 0xd800 || code >= 0xe000) {
  2963. buffer8[i++] = 0xe0 | code >> 12;
  2964. buffer8[i++] = 0x80 | code >> 6 & 0x3f;
  2965. buffer8[i++] = 0x80 | code & 0x3f;
  2966. } else {
  2967. code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++index) & 0x3ff);
  2968. buffer8[i++] = 0xf0 | code >> 18;
  2969. buffer8[i++] = 0x80 | code >> 12 & 0x3f;
  2970. buffer8[i++] = 0x80 | code >> 6 & 0x3f;
  2971. buffer8[i++] = 0x80 | code & 0x3f;
  2972. }
  2973. }
  2974. } else {
  2975. for (i = this.start; index < length && i < 64; ++index) {
  2976. code = message.charCodeAt(index);
  2977. if (isBinStr || code < 0x80) {
  2978. blocks[i >> 2] |= code << SHIFT[i++ & 3];
  2979. } else if (code < 0x800) {
  2980. blocks[i >> 2] |= (0xc0 | code >> 6) << SHIFT[i++ & 3];
  2981. blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
  2982. } else if (code < 0xd800 || code >= 0xe000) {
  2983. blocks[i >> 2] |= (0xe0 | code >> 12) << SHIFT[i++ & 3];
  2984. blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];
  2985. blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
  2986. } else {
  2987. code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++index) & 0x3ff);
  2988. blocks[i >> 2] |= (0xf0 | code >> 18) << SHIFT[i++ & 3];
  2989. blocks[i >> 2] |= (0x80 | code >> 12 & 0x3f) << SHIFT[i++ & 3];
  2990. blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];
  2991. blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
  2992. }
  2993. }
  2994. }
  2995. this.lastByteIndex = i;
  2996. this.bytes += i - this.start;
  2997. if (i >= 64) {
  2998. this.start = i - 64;
  2999. this.hash();
  3000. this.hashed = true;
  3001. } else {
  3002. this.start = i;
  3003. }
  3004. }
  3005. if (this.bytes > 4294967295) {
  3006. this.hBytes += this.bytes / 4294967296 << 0;
  3007. this.bytes = this.bytes % 4294967296;
  3008. }
  3009. return this;
  3010. };
  3011. Md5.prototype.finalize = function () {
  3012. if (this.finalized) {
  3013. return;
  3014. }
  3015. this.finalized = true;
  3016. var blocks = this.blocks,
  3017. i = this.lastByteIndex;
  3018. blocks[i >> 2] |= EXTRA[i & 3];
  3019. if (i >= 56) {
  3020. if (!this.hashed) {
  3021. this.hash();
  3022. }
  3023. blocks[0] = blocks[16];
  3024. blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
  3025. }
  3026. blocks[14] = this.bytes << 3;
  3027. blocks[15] = this.hBytes << 3 | this.bytes >>> 29;
  3028. this.hash();
  3029. };
  3030. Md5.prototype.hash = function () {
  3031. var a,
  3032. b,
  3033. c,
  3034. d,
  3035. bc,
  3036. da,
  3037. blocks = this.blocks;
  3038. if (this.first) {
  3039. a = blocks[0] - 680876937;
  3040. a = (a << 7 | a >>> 25) - 271733879 << 0;
  3041. d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;
  3042. d = (d << 12 | d >>> 20) + a << 0;
  3043. c = (-271733879 ^ d & (a ^ -271733879)) + blocks[2] - 1126478375;
  3044. c = (c << 17 | c >>> 15) + d << 0;
  3045. b = (a ^ c & (d ^ a)) + blocks[3] - 1316259209;
  3046. b = (b << 22 | b >>> 10) + c << 0;
  3047. } else {
  3048. a = this.h0;
  3049. b = this.h1;
  3050. c = this.h2;
  3051. d = this.h3;
  3052. a += (d ^ b & (c ^ d)) + blocks[0] - 680876936;
  3053. a = (a << 7 | a >>> 25) + b << 0;
  3054. d += (c ^ a & (b ^ c)) + blocks[1] - 389564586;
  3055. d = (d << 12 | d >>> 20) + a << 0;
  3056. c += (b ^ d & (a ^ b)) + blocks[2] + 606105819;
  3057. c = (c << 17 | c >>> 15) + d << 0;
  3058. b += (a ^ c & (d ^ a)) + blocks[3] - 1044525330;
  3059. b = (b << 22 | b >>> 10) + c << 0;
  3060. }
  3061. a += (d ^ b & (c ^ d)) + blocks[4] - 176418897;
  3062. a = (a << 7 | a >>> 25) + b << 0;
  3063. d += (c ^ a & (b ^ c)) + blocks[5] + 1200080426;
  3064. d = (d << 12 | d >>> 20) + a << 0;
  3065. c += (b ^ d & (a ^ b)) + blocks[6] - 1473231341;
  3066. c = (c << 17 | c >>> 15) + d << 0;
  3067. b += (a ^ c & (d ^ a)) + blocks[7] - 45705983;
  3068. b = (b << 22 | b >>> 10) + c << 0;
  3069. a += (d ^ b & (c ^ d)) + blocks[8] + 1770035416;
  3070. a = (a << 7 | a >>> 25) + b << 0;
  3071. d += (c ^ a & (b ^ c)) + blocks[9] - 1958414417;
  3072. d = (d << 12 | d >>> 20) + a << 0;
  3073. c += (b ^ d & (a ^ b)) + blocks[10] - 42063;
  3074. c = (c << 17 | c >>> 15) + d << 0;
  3075. b += (a ^ c & (d ^ a)) + blocks[11] - 1990404162;
  3076. b = (b << 22 | b >>> 10) + c << 0;
  3077. a += (d ^ b & (c ^ d)) + blocks[12] + 1804603682;
  3078. a = (a << 7 | a >>> 25) + b << 0;
  3079. d += (c ^ a & (b ^ c)) + blocks[13] - 40341101;
  3080. d = (d << 12 | d >>> 20) + a << 0;
  3081. c += (b ^ d & (a ^ b)) + blocks[14] - 1502002290;
  3082. c = (c << 17 | c >>> 15) + d << 0;
  3083. b += (a ^ c & (d ^ a)) + blocks[15] + 1236535329;
  3084. b = (b << 22 | b >>> 10) + c << 0;
  3085. a += (c ^ d & (b ^ c)) + blocks[1] - 165796510;
  3086. a = (a << 5 | a >>> 27) + b << 0;
  3087. d += (b ^ c & (a ^ b)) + blocks[6] - 1069501632;
  3088. d = (d << 9 | d >>> 23) + a << 0;
  3089. c += (a ^ b & (d ^ a)) + blocks[11] + 643717713;
  3090. c = (c << 14 | c >>> 18) + d << 0;
  3091. b += (d ^ a & (c ^ d)) + blocks[0] - 373897302;
  3092. b = (b << 20 | b >>> 12) + c << 0;
  3093. a += (c ^ d & (b ^ c)) + blocks[5] - 701558691;
  3094. a = (a << 5 | a >>> 27) + b << 0;
  3095. d += (b ^ c & (a ^ b)) + blocks[10] + 38016083;
  3096. d = (d << 9 | d >>> 23) + a << 0;
  3097. c += (a ^ b & (d ^ a)) + blocks[15] - 660478335;
  3098. c = (c << 14 | c >>> 18) + d << 0;
  3099. b += (d ^ a & (c ^ d)) + blocks[4] - 405537848;
  3100. b = (b << 20 | b >>> 12) + c << 0;
  3101. a += (c ^ d & (b ^ c)) + blocks[9] + 568446438;
  3102. a = (a << 5 | a >>> 27) + b << 0;
  3103. d += (b ^ c & (a ^ b)) + blocks[14] - 1019803690;
  3104. d = (d << 9 | d >>> 23) + a << 0;
  3105. c += (a ^ b & (d ^ a)) + blocks[3] - 187363961;
  3106. c = (c << 14 | c >>> 18) + d << 0;
  3107. b += (d ^ a & (c ^ d)) + blocks[8] + 1163531501;
  3108. b = (b << 20 | b >>> 12) + c << 0;
  3109. a += (c ^ d & (b ^ c)) + blocks[13] - 1444681467;
  3110. a = (a << 5 | a >>> 27) + b << 0;
  3111. d += (b ^ c & (a ^ b)) + blocks[2] - 51403784;
  3112. d = (d << 9 | d >>> 23) + a << 0;
  3113. c += (a ^ b & (d ^ a)) + blocks[7] + 1735328473;
  3114. c = (c << 14 | c >>> 18) + d << 0;
  3115. b += (d ^ a & (c ^ d)) + blocks[12] - 1926607734;
  3116. b = (b << 20 | b >>> 12) + c << 0;
  3117. bc = b ^ c;
  3118. a += (bc ^ d) + blocks[5] - 378558;
  3119. a = (a << 4 | a >>> 28) + b << 0;
  3120. d += (bc ^ a) + blocks[8] - 2022574463;
  3121. d = (d << 11 | d >>> 21) + a << 0;
  3122. da = d ^ a;
  3123. c += (da ^ b) + blocks[11] + 1839030562;
  3124. c = (c << 16 | c >>> 16) + d << 0;
  3125. b += (da ^ c) + blocks[14] - 35309556;
  3126. b = (b << 23 | b >>> 9) + c << 0;
  3127. bc = b ^ c;
  3128. a += (bc ^ d) + blocks[1] - 1530992060;
  3129. a = (a << 4 | a >>> 28) + b << 0;
  3130. d += (bc ^ a) + blocks[4] + 1272893353;
  3131. d = (d << 11 | d >>> 21) + a << 0;
  3132. da = d ^ a;
  3133. c += (da ^ b) + blocks[7] - 155497632;
  3134. c = (c << 16 | c >>> 16) + d << 0;
  3135. b += (da ^ c) + blocks[10] - 1094730640;
  3136. b = (b << 23 | b >>> 9) + c << 0;
  3137. bc = b ^ c;
  3138. a += (bc ^ d) + blocks[13] + 681279174;
  3139. a = (a << 4 | a >>> 28) + b << 0;
  3140. d += (bc ^ a) + blocks[0] - 358537222;
  3141. d = (d << 11 | d >>> 21) + a << 0;
  3142. da = d ^ a;
  3143. c += (da ^ b) + blocks[3] - 722521979;
  3144. c = (c << 16 | c >>> 16) + d << 0;
  3145. b += (da ^ c) + blocks[6] + 76029189;
  3146. b = (b << 23 | b >>> 9) + c << 0;
  3147. bc = b ^ c;
  3148. a += (bc ^ d) + blocks[9] - 640364487;
  3149. a = (a << 4 | a >>> 28) + b << 0;
  3150. d += (bc ^ a) + blocks[12] - 421815835;
  3151. d = (d << 11 | d >>> 21) + a << 0;
  3152. da = d ^ a;
  3153. c += (da ^ b) + blocks[15] + 530742520;
  3154. c = (c << 16 | c >>> 16) + d << 0;
  3155. b += (da ^ c) + blocks[2] - 995338651;
  3156. b = (b << 23 | b >>> 9) + c << 0;
  3157. a += (c ^ (b | ~d)) + blocks[0] - 198630844;
  3158. a = (a << 6 | a >>> 26) + b << 0;
  3159. d += (b ^ (a | ~c)) + blocks[7] + 1126891415;
  3160. d = (d << 10 | d >>> 22) + a << 0;
  3161. c += (a ^ (d | ~b)) + blocks[14] - 1416354905;
  3162. c = (c << 15 | c >>> 17) + d << 0;
  3163. b += (d ^ (c | ~a)) + blocks[5] - 57434055;
  3164. b = (b << 21 | b >>> 11) + c << 0;
  3165. a += (c ^ (b | ~d)) + blocks[12] + 1700485571;
  3166. a = (a << 6 | a >>> 26) + b << 0;
  3167. d += (b ^ (a | ~c)) + blocks[3] - 1894986606;
  3168. d = (d << 10 | d >>> 22) + a << 0;
  3169. c += (a ^ (d | ~b)) + blocks[10] - 1051523;
  3170. c = (c << 15 | c >>> 17) + d << 0;
  3171. b += (d ^ (c | ~a)) + blocks[1] - 2054922799;
  3172. b = (b << 21 | b >>> 11) + c << 0;
  3173. a += (c ^ (b | ~d)) + blocks[8] + 1873313359;
  3174. a = (a << 6 | a >>> 26) + b << 0;
  3175. d += (b ^ (a | ~c)) + blocks[15] - 30611744;
  3176. d = (d << 10 | d >>> 22) + a << 0;
  3177. c += (a ^ (d | ~b)) + blocks[6] - 1560198380;
  3178. c = (c << 15 | c >>> 17) + d << 0;
  3179. b += (d ^ (c | ~a)) + blocks[13] + 1309151649;
  3180. b = (b << 21 | b >>> 11) + c << 0;
  3181. a += (c ^ (b | ~d)) + blocks[4] - 145523070;
  3182. a = (a << 6 | a >>> 26) + b << 0;
  3183. d += (b ^ (a | ~c)) + blocks[11] - 1120210379;
  3184. d = (d << 10 | d >>> 22) + a << 0;
  3185. c += (a ^ (d | ~b)) + blocks[2] + 718787259;
  3186. c = (c << 15 | c >>> 17) + d << 0;
  3187. b += (d ^ (c | ~a)) + blocks[9] - 343485551;
  3188. b = (b << 21 | b >>> 11) + c << 0;
  3189. if (this.first) {
  3190. this.h0 = a + 1732584193 << 0;
  3191. this.h1 = b - 271733879 << 0;
  3192. this.h2 = c - 1732584194 << 0;
  3193. this.h3 = d + 271733878 << 0;
  3194. this.first = false;
  3195. } else {
  3196. this.h0 = this.h0 + a << 0;
  3197. this.h1 = this.h1 + b << 0;
  3198. this.h2 = this.h2 + c << 0;
  3199. this.h3 = this.h3 + d << 0;
  3200. }
  3201. };
  3202. /**
  3203. * @method hex
  3204. * @memberof Md5
  3205. * @instance
  3206. * @description Output hash as hex string
  3207. * @returns {String} Hex string
  3208. * @see {@link md5.hex}
  3209. * @example
  3210. * hash.hex();
  3211. */
  3212. Md5.prototype.hex = function () {
  3213. this.finalize();
  3214. var h0 = this.h0,
  3215. h1 = this.h1,
  3216. h2 = this.h2,
  3217. h3 = this.h3;
  3218. return HEX_CHARS[h0 >> 4 & 0x0F] + HEX_CHARS[h0 & 0x0F] + HEX_CHARS[h0 >> 12 & 0x0F] + HEX_CHARS[h0 >> 8 & 0x0F] + HEX_CHARS[h0 >> 20 & 0x0F] + HEX_CHARS[h0 >> 16 & 0x0F] + HEX_CHARS[h0 >> 28 & 0x0F] + HEX_CHARS[h0 >> 24 & 0x0F] + HEX_CHARS[h1 >> 4 & 0x0F] + HEX_CHARS[h1 & 0x0F] + HEX_CHARS[h1 >> 12 & 0x0F] + HEX_CHARS[h1 >> 8 & 0x0F] + HEX_CHARS[h1 >> 20 & 0x0F] + HEX_CHARS[h1 >> 16 & 0x0F] + HEX_CHARS[h1 >> 28 & 0x0F] + HEX_CHARS[h1 >> 24 & 0x0F] + HEX_CHARS[h2 >> 4 & 0x0F] + HEX_CHARS[h2 & 0x0F] + HEX_CHARS[h2 >> 12 & 0x0F] + HEX_CHARS[h2 >> 8 & 0x0F] + HEX_CHARS[h2 >> 20 & 0x0F] + HEX_CHARS[h2 >> 16 & 0x0F] + HEX_CHARS[h2 >> 28 & 0x0F] + HEX_CHARS[h2 >> 24 & 0x0F] + HEX_CHARS[h3 >> 4 & 0x0F] + HEX_CHARS[h3 & 0x0F] + HEX_CHARS[h3 >> 12 & 0x0F] + HEX_CHARS[h3 >> 8 & 0x0F] + HEX_CHARS[h3 >> 20 & 0x0F] + HEX_CHARS[h3 >> 16 & 0x0F] + HEX_CHARS[h3 >> 28 & 0x0F] + HEX_CHARS[h3 >> 24 & 0x0F];
  3219. };
  3220. /**
  3221. * @method toString
  3222. * @memberof Md5
  3223. * @instance
  3224. * @description Output hash as hex string
  3225. * @returns {String} Hex string
  3226. * @see {@link md5.hex}
  3227. * @example
  3228. * hash.toString();
  3229. */
  3230. Md5.prototype.toString = Md5.prototype.hex;
  3231. /**
  3232. * @method digest
  3233. * @memberof Md5
  3234. * @instance
  3235. * @description Output hash as bytes array
  3236. * @returns {Array} Bytes array
  3237. * @see {@link md5.digest}
  3238. * @example
  3239. * hash.digest();
  3240. */
  3241. Md5.prototype.digest = function (format) {
  3242. if (format === 'hex') return this.hex();
  3243. this.finalize();
  3244. var h0 = this.h0,
  3245. h1 = this.h1,
  3246. h2 = this.h2,
  3247. h3 = this.h3;
  3248. var res = [h0 & 0xFF, h0 >> 8 & 0xFF, h0 >> 16 & 0xFF, h0 >> 24 & 0xFF, h1 & 0xFF, h1 >> 8 & 0xFF, h1 >> 16 & 0xFF, h1 >> 24 & 0xFF, h2 & 0xFF, h2 >> 8 & 0xFF, h2 >> 16 & 0xFF, h2 >> 24 & 0xFF, h3 & 0xFF, h3 >> 8 & 0xFF, h3 >> 16 & 0xFF, h3 >> 24 & 0xFF];
  3249. return res;
  3250. };
  3251. /**
  3252. * @method array
  3253. * @memberof Md5
  3254. * @instance
  3255. * @description Output hash as bytes array
  3256. * @returns {Array} Bytes array
  3257. * @see {@link md5.array}
  3258. * @example
  3259. * hash.array();
  3260. */
  3261. Md5.prototype.array = Md5.prototype.digest;
  3262. /**
  3263. * @method arrayBuffer
  3264. * @memberof Md5
  3265. * @instance
  3266. * @description Output hash as ArrayBuffer
  3267. * @returns {ArrayBuffer} ArrayBuffer
  3268. * @see {@link md5.arrayBuffer}
  3269. * @example
  3270. * hash.arrayBuffer();
  3271. */
  3272. Md5.prototype.arrayBuffer = function () {
  3273. this.finalize();
  3274. var buffer = new ArrayBuffer(16);
  3275. var blocks = new Uint32Array(buffer);
  3276. blocks[0] = this.h0;
  3277. blocks[1] = this.h1;
  3278. blocks[2] = this.h2;
  3279. blocks[3] = this.h3;
  3280. return buffer;
  3281. };
  3282. /**
  3283. * @method buffer
  3284. * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
  3285. * @memberof Md5
  3286. * @instance
  3287. * @description Output hash as ArrayBuffer
  3288. * @returns {ArrayBuffer} ArrayBuffer
  3289. * @see {@link md5.buffer}
  3290. * @example
  3291. * hash.buffer();
  3292. */
  3293. Md5.prototype.buffer = Md5.prototype.arrayBuffer;
  3294. /**
  3295. * @method base64
  3296. * @memberof Md5
  3297. * @instance
  3298. * @description Output hash as base64 string
  3299. * @returns {String} base64 string
  3300. * @see {@link md5.base64}
  3301. * @example
  3302. * hash.base64();
  3303. */
  3304. Md5.prototype.base64 = function () {
  3305. var v1,
  3306. v2,
  3307. v3,
  3308. base64Str = '',
  3309. bytes = this.array();
  3310. for (var i = 0; i < 15;) {
  3311. v1 = bytes[i++];
  3312. v2 = bytes[i++];
  3313. v3 = bytes[i++];
  3314. base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] + BASE64_ENCODE_CHAR[(v1 << 4 | v2 >>> 4) & 63] + BASE64_ENCODE_CHAR[(v2 << 2 | v3 >>> 6) & 63] + BASE64_ENCODE_CHAR[v3 & 63];
  3315. }
  3316. v1 = bytes[i];
  3317. base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] + BASE64_ENCODE_CHAR[v1 << 4 & 63] + '==';
  3318. return base64Str;
  3319. };
  3320. var exports = createMethod();
  3321. if (COMMON_JS) {
  3322. module.exports = exports;
  3323. } else {
  3324. /**
  3325. * @method md5
  3326. * @description Md5 hash function, export to global in browsers.
  3327. * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
  3328. * @returns {String} md5 hashes
  3329. * @example
  3330. * md5(''); // d41d8cd98f00b204e9800998ecf8427e
  3331. * md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6
  3332. * md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0
  3333. *
  3334. * // It also supports UTF-8 encoding
  3335. * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07
  3336. *
  3337. * // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`
  3338. * md5([]); // d41d8cd98f00b204e9800998ecf8427e
  3339. * md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e
  3340. */
  3341. root.md5 = exports;
  3342. if (AMD) {
  3343. !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
  3344. return exports;
  3345. }).call(exports, __webpack_require__, exports, module),
  3346. __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  3347. }
  3348. }
  3349. })();
  3350. /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2), __webpack_require__(9)))
  3351. /***/ }),
  3352. /* 9 */
  3353. /***/ (function(module, exports) {
  3354. var g;
  3355. // This works in non-strict mode
  3356. g = (function() {
  3357. return this;
  3358. })();
  3359. try {
  3360. // This works if eval is allowed (see CSP)
  3361. g = g || Function("return this")() || (1,eval)("this");
  3362. } catch(e) {
  3363. // This works if the window reference is available
  3364. if(typeof window === "object")
  3365. g = window;
  3366. }
  3367. // g can still be undefined, but nothing to do about it...
  3368. // We return undefined, instead of nothing here, so it's
  3369. // easier to handle this case. if(!global) { ...}
  3370. module.exports = g;
  3371. /***/ }),
  3372. /* 10 */
  3373. /***/ (function(module, exports) {
  3374. /* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
  3375. module.exports = __webpack_amd_options__;
  3376. /* WEBPACK VAR INJECTION */}.call(exports, {}))
  3377. /***/ }),
  3378. /* 11 */
  3379. /***/ (function(module, exports, __webpack_require__) {
  3380. /*
  3381. CryptoJS v3.1.2
  3382. code.google.com/p/crypto-js
  3383. (c) 2009-2013 by Jeff Mott. All rights reserved.
  3384. code.google.com/p/crypto-js/wiki/License
  3385. */
  3386. var CryptoJS = CryptoJS || function (g, l) {
  3387. var e = {},
  3388. d = e.lib = {},
  3389. m = function () {},
  3390. k = d.Base = { extend: function (a) {
  3391. m.prototype = this;var c = new m();a && c.mixIn(a);c.hasOwnProperty("init") || (c.init = function () {
  3392. c.$super.init.apply(this, arguments);
  3393. });c.init.prototype = c;c.$super = this;return c;
  3394. }, create: function () {
  3395. var a = this.extend();a.init.apply(a, arguments);return a;
  3396. }, init: function () {}, mixIn: function (a) {
  3397. for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]);a.hasOwnProperty("toString") && (this.toString = a.toString);
  3398. }, clone: function () {
  3399. return this.init.prototype.extend(this);
  3400. } },
  3401. p = d.WordArray = k.extend({ init: function (a, c) {
  3402. a = this.words = a || [];this.sigBytes = c != l ? c : 4 * a.length;
  3403. }, toString: function (a) {
  3404. return (a || n).stringify(this);
  3405. }, concat: function (a) {
  3406. var c = this.words,
  3407. q = a.words,
  3408. f = this.sigBytes;a = a.sigBytes;this.clamp();if (f % 4) for (var b = 0; b < a; b++) c[f + b >>> 2] |= (q[b >>> 2] >>> 24 - 8 * (b % 4) & 255) << 24 - 8 * ((f + b) % 4);else if (65535 < q.length) for (b = 0; b < a; b += 4) c[f + b >>> 2] = q[b >>> 2];else c.push.apply(c, q);this.sigBytes += a;return this;
  3409. }, clamp: function () {
  3410. var a = this.words,
  3411. c = this.sigBytes;a[c >>> 2] &= 4294967295 << 32 - 8 * (c % 4);a.length = g.ceil(c / 4);
  3412. }, clone: function () {
  3413. var a = k.clone.call(this);a.words = this.words.slice(0);return a;
  3414. }, random: function (a) {
  3415. for (var c = [], b = 0; b < a; b += 4) c.push(4294967296 * g.random() | 0);return new p.init(c, a);
  3416. } }),
  3417. b = e.enc = {},
  3418. n = b.Hex = { stringify: function (a) {
  3419. var c = a.words;a = a.sigBytes;for (var b = [], f = 0; f < a; f++) {
  3420. var d = c[f >>> 2] >>> 24 - 8 * (f % 4) & 255;b.push((d >>> 4).toString(16));b.push((d & 15).toString(16));
  3421. }return b.join("");
  3422. }, parse: function (a) {
  3423. for (var c = a.length, b = [], f = 0; f < c; f += 2) b[f >>> 3] |= parseInt(a.substr(f, 2), 16) << 24 - 4 * (f % 8);return new p.init(b, c / 2);
  3424. } },
  3425. j = b.Latin1 = { stringify: function (a) {
  3426. var c = a.words;a = a.sigBytes;for (var b = [], f = 0; f < a; f++) b.push(String.fromCharCode(c[f >>> 2] >>> 24 - 8 * (f % 4) & 255));return b.join("");
  3427. }, parse: function (a) {
  3428. for (var c = a.length, b = [], f = 0; f < c; f++) b[f >>> 2] |= (a.charCodeAt(f) & 255) << 24 - 8 * (f % 4);return new p.init(b, c);
  3429. } },
  3430. h = b.Utf8 = { stringify: function (a) {
  3431. try {
  3432. return decodeURIComponent(escape(j.stringify(a)));
  3433. } catch (c) {
  3434. throw Error("Malformed UTF-8 data");
  3435. }
  3436. }, parse: function (a) {
  3437. return j.parse(unescape(encodeURIComponent(a)));
  3438. } },
  3439. r = d.BufferedBlockAlgorithm = k.extend({ reset: function () {
  3440. this._data = new p.init();this._nDataBytes = 0;
  3441. }, _append: function (a) {
  3442. "string" == typeof a && (a = h.parse(a));this._data.concat(a);this._nDataBytes += a.sigBytes;
  3443. }, _process: function (a) {
  3444. var c = this._data,
  3445. b = c.words,
  3446. f = c.sigBytes,
  3447. d = this.blockSize,
  3448. e = f / (4 * d),
  3449. e = a ? g.ceil(e) : g.max((e | 0) - this._minBufferSize, 0);a = e * d;f = g.min(4 * a, f);if (a) {
  3450. for (var k = 0; k < a; k += d) this._doProcessBlock(b, k);k = b.splice(0, a);c.sigBytes -= f;
  3451. }return new p.init(k, f);
  3452. }, clone: function () {
  3453. var a = k.clone.call(this);
  3454. a._data = this._data.clone();return a;
  3455. }, _minBufferSize: 0 });d.Hasher = r.extend({ cfg: k.extend(), init: function (a) {
  3456. this.cfg = this.cfg.extend(a);this.reset();
  3457. }, reset: function () {
  3458. r.reset.call(this);this._doReset();
  3459. }, update: function (a) {
  3460. this._append(a);this._process();return this;
  3461. }, finalize: function (a) {
  3462. a && this._append(a);return this._doFinalize();
  3463. }, blockSize: 16, _createHelper: function (a) {
  3464. return function (b, d) {
  3465. return new a.init(d).finalize(b);
  3466. };
  3467. }, _createHmacHelper: function (a) {
  3468. return function (b, d) {
  3469. return new s.HMAC.init(a, d).finalize(b);
  3470. };
  3471. } });var s = e.algo = {};return e;
  3472. }(Math);
  3473. (function () {
  3474. var g = CryptoJS,
  3475. l = g.lib,
  3476. e = l.WordArray,
  3477. d = l.Hasher,
  3478. m = [],
  3479. l = g.algo.SHA1 = d.extend({ _doReset: function () {
  3480. this._hash = new e.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]);
  3481. }, _doProcessBlock: function (d, e) {
  3482. for (var b = this._hash.words, n = b[0], j = b[1], h = b[2], g = b[3], l = b[4], a = 0; 80 > a; a++) {
  3483. if (16 > a) m[a] = d[e + a] | 0;else {
  3484. var c = m[a - 3] ^ m[a - 8] ^ m[a - 14] ^ m[a - 16];m[a] = c << 1 | c >>> 31;
  3485. }c = (n << 5 | n >>> 27) + l + m[a];c = 20 > a ? c + ((j & h | ~j & g) + 1518500249) : 40 > a ? c + ((j ^ h ^ g) + 1859775393) : 60 > a ? c + ((j & h | j & g | h & g) - 1894007588) : c + ((j ^ h ^ g) - 899497514);l = g;g = h;h = j << 30 | j >>> 2;j = n;n = c;
  3486. }b[0] = b[0] + n | 0;b[1] = b[1] + j | 0;b[2] = b[2] + h | 0;b[3] = b[3] + g | 0;b[4] = b[4] + l | 0;
  3487. }, _doFinalize: function () {
  3488. var d = this._data,
  3489. e = d.words,
  3490. b = 8 * this._nDataBytes,
  3491. g = 8 * d.sigBytes;e[g >>> 5] |= 128 << 24 - g % 32;e[(g + 64 >>> 9 << 4) + 14] = Math.floor(b / 4294967296);e[(g + 64 >>> 9 << 4) + 15] = b;d.sigBytes = 4 * e.length;this._process();return this._hash;
  3492. }, clone: function () {
  3493. var e = d.clone.call(this);e._hash = this._hash.clone();return e;
  3494. } });g.SHA1 = d._createHelper(l);g.HmacSHA1 = d._createHmacHelper(l);
  3495. })();
  3496. (function () {
  3497. var g = CryptoJS,
  3498. l = g.enc.Utf8;g.algo.HMAC = g.lib.Base.extend({ init: function (e, d) {
  3499. e = this._hasher = new e.init();"string" == typeof d && (d = l.parse(d));var g = e.blockSize,
  3500. k = 4 * g;d.sigBytes > k && (d = e.finalize(d));d.clamp();for (var p = this._oKey = d.clone(), b = this._iKey = d.clone(), n = p.words, j = b.words, h = 0; h < g; h++) n[h] ^= 1549556828, j[h] ^= 909522486;p.sigBytes = b.sigBytes = k;this.reset();
  3501. }, reset: function () {
  3502. var e = this._hasher;e.reset();e.update(this._iKey);
  3503. }, update: function (e) {
  3504. this._hasher.update(e);return this;
  3505. }, finalize: function (e) {
  3506. var d = this._hasher;e = d.finalize(e);d.reset();return d.finalize(this._oKey.clone().concat(e));
  3507. } });
  3508. })();
  3509. (function () {
  3510. // Shortcuts
  3511. var C = CryptoJS;
  3512. var C_lib = C.lib;
  3513. var WordArray = C_lib.WordArray;
  3514. var C_enc = C.enc;
  3515. /**
  3516. * Base64 encoding strategy.
  3517. */
  3518. var Base64 = C_enc.Base64 = {
  3519. /**
  3520. * Converts a word array to a Base64 string.
  3521. *
  3522. * @param {WordArray} wordArray The word array.
  3523. *
  3524. * @return {string} The Base64 string.
  3525. *
  3526. * @static
  3527. *
  3528. * @example
  3529. *
  3530. * var base64String = CryptoJS.enc.Base64.stringify(wordArray);
  3531. */
  3532. stringify: function (wordArray) {
  3533. // Shortcuts
  3534. var words = wordArray.words;
  3535. var sigBytes = wordArray.sigBytes;
  3536. var map = this._map;
  3537. // Clamp excess bits
  3538. wordArray.clamp();
  3539. // Convert
  3540. var base64Chars = [];
  3541. for (var i = 0; i < sigBytes; i += 3) {
  3542. var byte1 = words[i >>> 2] >>> 24 - i % 4 * 8 & 0xff;
  3543. var byte2 = words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 0xff;
  3544. var byte3 = words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 0xff;
  3545. var triplet = byte1 << 16 | byte2 << 8 | byte3;
  3546. for (var j = 0; j < 4 && i + j * 0.75 < sigBytes; j++) {
  3547. base64Chars.push(map.charAt(triplet >>> 6 * (3 - j) & 0x3f));
  3548. }
  3549. }
  3550. // Add padding
  3551. var paddingChar = map.charAt(64);
  3552. if (paddingChar) {
  3553. while (base64Chars.length % 4) {
  3554. base64Chars.push(paddingChar);
  3555. }
  3556. }
  3557. return base64Chars.join('');
  3558. },
  3559. /**
  3560. * Converts a Base64 string to a word array.
  3561. *
  3562. * @param {string} base64Str The Base64 string.
  3563. *
  3564. * @return {WordArray} The word array.
  3565. *
  3566. * @static
  3567. *
  3568. * @example
  3569. *
  3570. * var wordArray = CryptoJS.enc.Base64.parse(base64String);
  3571. */
  3572. parse: function (base64Str) {
  3573. // Shortcuts
  3574. var base64StrLength = base64Str.length;
  3575. var map = this._map;
  3576. // Ignore padding
  3577. var paddingChar = map.charAt(64);
  3578. if (paddingChar) {
  3579. var paddingIndex = base64Str.indexOf(paddingChar);
  3580. if (paddingIndex != -1) {
  3581. base64StrLength = paddingIndex;
  3582. }
  3583. }
  3584. // Convert
  3585. var words = [];
  3586. var nBytes = 0;
  3587. for (var i = 0; i < base64StrLength; i++) {
  3588. if (i % 4) {
  3589. var bits1 = map.indexOf(base64Str.charAt(i - 1)) << i % 4 * 2;
  3590. var bits2 = map.indexOf(base64Str.charAt(i)) >>> 6 - i % 4 * 2;
  3591. words[nBytes >>> 2] |= (bits1 | bits2) << 24 - nBytes % 4 * 8;
  3592. nBytes++;
  3593. }
  3594. }
  3595. return WordArray.create(words, nBytes);
  3596. },
  3597. _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
  3598. };
  3599. })();
  3600. if (true) {
  3601. module.exports = CryptoJS;
  3602. } else {
  3603. window.CryptoJS = CryptoJS;
  3604. }
  3605. /***/ }),
  3606. /* 12 */
  3607. /***/ (function(module, exports, __webpack_require__) {
  3608. /* Copyright 2015 William Summers, MetaTribal LLC
  3609. * adapted from https://developer.mozilla.org/en-US/docs/JXON
  3610. *
  3611. * Licensed under the MIT License, Version 2.0 (the "License");
  3612. * you may not use this file except in compliance with the License.
  3613. * You may obtain a copy of the License at
  3614. *
  3615. * https://opensource.org/licenses/MIT
  3616. *
  3617. * Unless required by applicable law or agreed to in writing, software
  3618. * distributed under the License is distributed on an "AS IS" BASIS,
  3619. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3620. * See the License for the specific language governing permissions and
  3621. * limitations under the License.
  3622. */
  3623. /**
  3624. * @author William Summers
  3625. * https://github.com/metatribal/xmlToJSON
  3626. */
  3627. var DOMParser = __webpack_require__(13).DOMParser;
  3628. var xmlToJSON = function () {
  3629. this.version = "1.3.5";
  3630. var options = { // set up the default options
  3631. mergeCDATA: true, // extract cdata and merge with text
  3632. normalize: true, // collapse multiple spaces to single space
  3633. stripElemPrefix: true // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
  3634. };
  3635. var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
  3636. var trimMatch = new RegExp(/^\s+|\s+$/g);
  3637. this.grokType = function (sValue) {
  3638. if (/^\s*$/.test(sValue)) {
  3639. return null;
  3640. }
  3641. if (/^(?:true|false)$/i.test(sValue)) {
  3642. return sValue.toLowerCase() === "true";
  3643. }
  3644. if (isFinite(sValue)) {
  3645. return parseFloat(sValue);
  3646. }
  3647. return sValue;
  3648. };
  3649. this.parseString = function (xmlString, opt) {
  3650. if (xmlString) {
  3651. var xml = this.stringToXML(xmlString);
  3652. if (xml.getElementsByTagName('parsererror').length) {
  3653. return null;
  3654. } else {
  3655. return this.parseXML(xml, opt);
  3656. }
  3657. } else {
  3658. return null;
  3659. }
  3660. };
  3661. this.parseXML = function (oXMLParent, opt) {
  3662. // initialize options
  3663. for (var key in opt) {
  3664. options[key] = opt[key];
  3665. }
  3666. var vResult = {},
  3667. nLength = 0,
  3668. sCollectedTxt = "";
  3669. // iterate over the children
  3670. var childNum = oXMLParent.childNodes.length;
  3671. if (childNum) {
  3672. for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
  3673. oNode = oXMLParent.childNodes.item(nItem);
  3674. if (oNode.nodeType === 4) {
  3675. if (options.mergeCDATA) {
  3676. sCollectedTxt += oNode.nodeValue;
  3677. }
  3678. } /* nodeType is "CDATASection" (4) */
  3679. else if (oNode.nodeType === 3) {
  3680. sCollectedTxt += oNode.nodeValue;
  3681. } /* nodeType is "Text" (3) */
  3682. else if (oNode.nodeType === 1) {
  3683. /* nodeType is "Element" (1) */
  3684. if (nLength === 0) {
  3685. vResult = {};
  3686. }
  3687. // using nodeName to support browser (IE) implementation with no 'localName' property
  3688. if (options.stripElemPrefix) {
  3689. sProp = oNode.nodeName.replace(prefixMatch, '');
  3690. } else {
  3691. sProp = oNode.nodeName;
  3692. }
  3693. vContent = xmlToJSON.parseXML(oNode);
  3694. if (vResult.hasOwnProperty(sProp)) {
  3695. if (vResult[sProp].constructor !== Array) {
  3696. vResult[sProp] = [vResult[sProp]];
  3697. }
  3698. vResult[sProp].push(vContent);
  3699. } else {
  3700. vResult[sProp] = vContent;
  3701. nLength++;
  3702. }
  3703. }
  3704. }
  3705. }
  3706. if (!Object.keys(vResult).length) {
  3707. // vResult = sCollectedTxt.replace(trimMatch, '') || ''; // by carsonxu 修复 getBucket返回的 Key 是 " /" 这种场景
  3708. vResult = sCollectedTxt || '';
  3709. }
  3710. return vResult;
  3711. };
  3712. // Convert xmlDocument to a string
  3713. // Returns null on failure
  3714. this.xmlToString = function (xmlDoc) {
  3715. try {
  3716. var xmlString = xmlDoc.xml ? xmlDoc.xml : new XMLSerializer().serializeToString(xmlDoc);
  3717. return xmlString;
  3718. } catch (err) {
  3719. return null;
  3720. }
  3721. };
  3722. // Convert a string to XML Node Structure
  3723. // Returns null on failure
  3724. this.stringToXML = function (xmlString) {
  3725. try {
  3726. var xmlDoc = null;
  3727. if (window.DOMParser) {
  3728. var parser = new DOMParser();
  3729. xmlDoc = parser.parseFromString(xmlString, "text/xml");
  3730. return xmlDoc;
  3731. } else {
  3732. xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  3733. xmlDoc.async = false;
  3734. xmlDoc.loadXML(xmlString);
  3735. return xmlDoc;
  3736. }
  3737. } catch (e) {
  3738. return null;
  3739. }
  3740. };
  3741. return this;
  3742. }.call({});
  3743. var xml2json = function (xmlString) {
  3744. return xmlToJSON.parseString(xmlString);
  3745. };
  3746. module.exports = xml2json;
  3747. /***/ }),
  3748. /* 13 */
  3749. /***/ (function(module, exports, __webpack_require__) {
  3750. var dom = __webpack_require__(3)
  3751. exports.DOMImplementation = dom.DOMImplementation
  3752. exports.XMLSerializer = dom.XMLSerializer
  3753. exports.DOMParser = __webpack_require__(14).DOMParser
  3754. /***/ }),
  3755. /* 14 */
  3756. /***/ (function(module, exports, __webpack_require__) {
  3757. var conventions = __webpack_require__(1);
  3758. var dom = __webpack_require__(3)
  3759. var entities = __webpack_require__(15);
  3760. var sax = __webpack_require__(16);
  3761. var DOMImplementation = dom.DOMImplementation;
  3762. var NAMESPACE = conventions.NAMESPACE;
  3763. var ParseError = sax.ParseError;
  3764. var XMLReader = sax.XMLReader;
  3765. /**
  3766. * Normalizes line ending according to https://www.w3.org/TR/xml11/#sec-line-ends:
  3767. *
  3768. * > XML parsed entities are often stored in computer files which,
  3769. * > for editing convenience, are organized into lines.
  3770. * > These lines are typically separated by some combination
  3771. * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA).
  3772. * >
  3773. * > To simplify the tasks of applications, the XML processor must behave
  3774. * > as if it normalized all line breaks in external parsed entities (including the document entity)
  3775. * > on input, before parsing, by translating all of the following to a single #xA character:
  3776. * >
  3777. * > 1. the two-character sequence #xD #xA
  3778. * > 2. the two-character sequence #xD #x85
  3779. * > 3. the single character #x85
  3780. * > 4. the single character #x2028
  3781. * > 5. any #xD character that is not immediately followed by #xA or #x85.
  3782. *
  3783. * @param {string} input
  3784. * @returns {string}
  3785. */
  3786. function normalizeLineEndings(input) {
  3787. return input
  3788. .replace(/\r[\n\u0085]/g, '\n')
  3789. .replace(/[\r\u0085\u2028]/g, '\n')
  3790. }
  3791. /**
  3792. * @typedef Locator
  3793. * @property {number} [columnNumber]
  3794. * @property {number} [lineNumber]
  3795. */
  3796. /**
  3797. * @typedef DOMParserOptions
  3798. * @property {DOMHandler} [domBuilder]
  3799. * @property {Function} [errorHandler]
  3800. * @property {(string) => string} [normalizeLineEndings] used to replace line endings before parsing
  3801. * defaults to `normalizeLineEndings`
  3802. * @property {Locator} [locator]
  3803. * @property {Record<string, string>} [xmlns]
  3804. *
  3805. * @see normalizeLineEndings
  3806. */
  3807. /**
  3808. * The DOMParser interface provides the ability to parse XML or HTML source code
  3809. * from a string into a DOM `Document`.
  3810. *
  3811. * _xmldom is different from the spec in that it allows an `options` parameter,
  3812. * to override the default behavior._
  3813. *
  3814. * @param {DOMParserOptions} [options]
  3815. * @constructor
  3816. *
  3817. * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
  3818. * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization
  3819. */
  3820. function DOMParser(options){
  3821. this.options = options ||{locator:{}};
  3822. }
  3823. DOMParser.prototype.parseFromString = function(source,mimeType){
  3824. var options = this.options;
  3825. var sax = new XMLReader();
  3826. var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
  3827. var errorHandler = options.errorHandler;
  3828. var locator = options.locator;
  3829. var defaultNSMap = options.xmlns||{};
  3830. var isHTML = /\/x?html?$/.test(mimeType);//mimeType.toLowerCase().indexOf('html') > -1;
  3831. var entityMap = isHTML ? entities.HTML_ENTITIES : entities.XML_ENTITIES;
  3832. if(locator){
  3833. domBuilder.setDocumentLocator(locator)
  3834. }
  3835. sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
  3836. sax.domBuilder = options.domBuilder || domBuilder;
  3837. if(isHTML){
  3838. defaultNSMap[''] = NAMESPACE.HTML;
  3839. }
  3840. defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML;
  3841. var normalize = options.normalizeLineEndings || normalizeLineEndings;
  3842. if (source && typeof source === 'string') {
  3843. sax.parse(
  3844. normalize(source),
  3845. defaultNSMap,
  3846. entityMap
  3847. )
  3848. } else {
  3849. sax.errorHandler.error('invalid doc source')
  3850. }
  3851. return domBuilder.doc;
  3852. }
  3853. function buildErrorHandler(errorImpl,domBuilder,locator){
  3854. if(!errorImpl){
  3855. if(domBuilder instanceof DOMHandler){
  3856. return domBuilder;
  3857. }
  3858. errorImpl = domBuilder ;
  3859. }
  3860. var errorHandler = {}
  3861. var isCallback = errorImpl instanceof Function;
  3862. locator = locator||{}
  3863. function build(key){
  3864. var fn = errorImpl[key];
  3865. if(!fn && isCallback){
  3866. fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
  3867. }
  3868. errorHandler[key] = fn && function(msg){
  3869. fn('[xmldom '+key+']\t'+msg+_locator(locator));
  3870. }||function(){};
  3871. }
  3872. build('warning');
  3873. build('error');
  3874. build('fatalError');
  3875. return errorHandler;
  3876. }
  3877. //console.log('#\n\n\n\n\n\n\n####')
  3878. /**
  3879. * +ContentHandler+ErrorHandler
  3880. * +LexicalHandler+EntityResolver2
  3881. * -DeclHandler-DTDHandler
  3882. *
  3883. * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
  3884. * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
  3885. * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
  3886. */
  3887. function DOMHandler() {
  3888. this.cdata = false;
  3889. }
  3890. function position(locator,node){
  3891. node.lineNumber = locator.lineNumber;
  3892. node.columnNumber = locator.columnNumber;
  3893. }
  3894. /**
  3895. * @see org.xml.sax.ContentHandler#startDocument
  3896. * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
  3897. */
  3898. DOMHandler.prototype = {
  3899. startDocument : function() {
  3900. this.doc = new DOMImplementation().createDocument(null, null, null);
  3901. if (this.locator) {
  3902. this.doc.documentURI = this.locator.systemId;
  3903. }
  3904. },
  3905. startElement:function(namespaceURI, localName, qName, attrs) {
  3906. var doc = this.doc;
  3907. var el = doc.createElementNS(namespaceURI, qName||localName);
  3908. var len = attrs.length;
  3909. appendElement(this, el);
  3910. this.currentElement = el;
  3911. this.locator && position(this.locator,el)
  3912. for (var i = 0 ; i < len; i++) {
  3913. var namespaceURI = attrs.getURI(i);
  3914. var value = attrs.getValue(i);
  3915. var qName = attrs.getQName(i);
  3916. var attr = doc.createAttributeNS(namespaceURI, qName);
  3917. this.locator &&position(attrs.getLocator(i),attr);
  3918. attr.value = attr.nodeValue = value;
  3919. el.setAttributeNode(attr)
  3920. }
  3921. },
  3922. endElement:function(namespaceURI, localName, qName) {
  3923. var current = this.currentElement
  3924. var tagName = current.tagName;
  3925. this.currentElement = current.parentNode;
  3926. },
  3927. startPrefixMapping:function(prefix, uri) {
  3928. },
  3929. endPrefixMapping:function(prefix) {
  3930. },
  3931. processingInstruction:function(target, data) {
  3932. var ins = this.doc.createProcessingInstruction(target, data);
  3933. this.locator && position(this.locator,ins)
  3934. appendElement(this, ins);
  3935. },
  3936. ignorableWhitespace:function(ch, start, length) {
  3937. },
  3938. characters:function(chars, start, length) {
  3939. chars = _toString.apply(this,arguments)
  3940. //console.log(chars)
  3941. if(chars){
  3942. if (this.cdata) {
  3943. var charNode = this.doc.createCDATASection(chars);
  3944. } else {
  3945. var charNode = this.doc.createTextNode(chars);
  3946. }
  3947. if(this.currentElement){
  3948. this.currentElement.appendChild(charNode);
  3949. }else if(/^\s*$/.test(chars)){
  3950. this.doc.appendChild(charNode);
  3951. //process xml
  3952. }
  3953. this.locator && position(this.locator,charNode)
  3954. }
  3955. },
  3956. skippedEntity:function(name) {
  3957. },
  3958. endDocument:function() {
  3959. this.doc.normalize();
  3960. },
  3961. setDocumentLocator:function (locator) {
  3962. if(this.locator = locator){// && !('lineNumber' in locator)){
  3963. locator.lineNumber = 0;
  3964. }
  3965. },
  3966. //LexicalHandler
  3967. comment:function(chars, start, length) {
  3968. chars = _toString.apply(this,arguments)
  3969. var comm = this.doc.createComment(chars);
  3970. this.locator && position(this.locator,comm)
  3971. appendElement(this, comm);
  3972. },
  3973. startCDATA:function() {
  3974. //used in characters() methods
  3975. this.cdata = true;
  3976. },
  3977. endCDATA:function() {
  3978. this.cdata = false;
  3979. },
  3980. startDTD:function(name, publicId, systemId) {
  3981. var impl = this.doc.implementation;
  3982. if (impl && impl.createDocumentType) {
  3983. var dt = impl.createDocumentType(name, publicId, systemId);
  3984. this.locator && position(this.locator,dt)
  3985. appendElement(this, dt);
  3986. this.doc.doctype = dt;
  3987. }
  3988. },
  3989. /**
  3990. * @see org.xml.sax.ErrorHandler
  3991. * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
  3992. */
  3993. warning:function(error) {
  3994. console.warn('[xmldom warning]\t'+error,_locator(this.locator));
  3995. },
  3996. error:function(error) {
  3997. console.error('[xmldom error]\t'+error,_locator(this.locator));
  3998. },
  3999. fatalError:function(error) {
  4000. throw new ParseError(error, this.locator);
  4001. }
  4002. }
  4003. function _locator(l){
  4004. if(l){
  4005. return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
  4006. }
  4007. }
  4008. function _toString(chars,start,length){
  4009. if(typeof chars == 'string'){
  4010. return chars.substr(start,length)
  4011. }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
  4012. if(chars.length >= start+length || start){
  4013. return new java.lang.String(chars,start,length)+'';
  4014. }
  4015. return chars;
  4016. }
  4017. }
  4018. /*
  4019. * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
  4020. * used method of org.xml.sax.ext.LexicalHandler:
  4021. * #comment(chars, start, length)
  4022. * #startCDATA()
  4023. * #endCDATA()
  4024. * #startDTD(name, publicId, systemId)
  4025. *
  4026. *
  4027. * IGNORED method of org.xml.sax.ext.LexicalHandler:
  4028. * #endDTD()
  4029. * #startEntity(name)
  4030. * #endEntity(name)
  4031. *
  4032. *
  4033. * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
  4034. * IGNORED method of org.xml.sax.ext.DeclHandler
  4035. * #attributeDecl(eName, aName, type, mode, value)
  4036. * #elementDecl(name, model)
  4037. * #externalEntityDecl(name, publicId, systemId)
  4038. * #internalEntityDecl(name, value)
  4039. * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
  4040. * IGNORED method of org.xml.sax.EntityResolver2
  4041. * #resolveEntity(String name,String publicId,String baseURI,String systemId)
  4042. * #resolveEntity(publicId, systemId)
  4043. * #getExternalSubset(name, baseURI)
  4044. * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
  4045. * IGNORED method of org.xml.sax.DTDHandler
  4046. * #notationDecl(name, publicId, systemId) {};
  4047. * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
  4048. */
  4049. "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
  4050. DOMHandler.prototype[key] = function(){return null}
  4051. })
  4052. /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
  4053. function appendElement (hander,node) {
  4054. if (!hander.currentElement) {
  4055. hander.doc.appendChild(node);
  4056. } else {
  4057. hander.currentElement.appendChild(node);
  4058. }
  4059. }//appendChild and setAttributeNS are preformance key
  4060. exports.__DOMHandler = DOMHandler;
  4061. exports.normalizeLineEndings = normalizeLineEndings;
  4062. exports.DOMParser = DOMParser;
  4063. /***/ }),
  4064. /* 15 */
  4065. /***/ (function(module, exports, __webpack_require__) {
  4066. var freeze = __webpack_require__(1).freeze;
  4067. /**
  4068. * The entities that are predefined in every XML document.
  4069. *
  4070. * @see https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-predefined-ent W3C XML 1.1
  4071. * @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent W3C XML 1.0
  4072. * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML Wikipedia
  4073. */
  4074. exports.XML_ENTITIES = freeze({amp:'&', apos:"'", gt:'>', lt:'<', quot:'"'})
  4075. /**
  4076. * A map of currently 241 entities that are detected in an HTML document.
  4077. * They contain all entries from `XML_ENTITIES`.
  4078. *
  4079. * @see XML_ENTITIES
  4080. * @see DOMParser.parseFromString
  4081. * @see DOMImplementation.prototype.createHTMLDocument
  4082. * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5) Spec
  4083. * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names
  4084. * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML
  4085. * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML Wikipedia (HTML)
  4086. * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML Wikpedia (XHTML)
  4087. */
  4088. exports.HTML_ENTITIES = freeze({
  4089. lt: '<',
  4090. gt: '>',
  4091. amp: '&',
  4092. quot: '"',
  4093. apos: "'",
  4094. Agrave: "À",
  4095. Aacute: "Á",
  4096. Acirc: "Â",
  4097. Atilde: "Ã",
  4098. Auml: "Ä",
  4099. Aring: "Å",
  4100. AElig: "Æ",
  4101. Ccedil: "Ç",
  4102. Egrave: "È",
  4103. Eacute: "É",
  4104. Ecirc: "Ê",
  4105. Euml: "Ë",
  4106. Igrave: "Ì",
  4107. Iacute: "Í",
  4108. Icirc: "Î",
  4109. Iuml: "Ï",
  4110. ETH: "Ð",
  4111. Ntilde: "Ñ",
  4112. Ograve: "Ò",
  4113. Oacute: "Ó",
  4114. Ocirc: "Ô",
  4115. Otilde: "Õ",
  4116. Ouml: "Ö",
  4117. Oslash: "Ø",
  4118. Ugrave: "Ù",
  4119. Uacute: "Ú",
  4120. Ucirc: "Û",
  4121. Uuml: "Ü",
  4122. Yacute: "Ý",
  4123. THORN: "Þ",
  4124. szlig: "ß",
  4125. agrave: "à",
  4126. aacute: "á",
  4127. acirc: "â",
  4128. atilde: "ã",
  4129. auml: "ä",
  4130. aring: "å",
  4131. aelig: "æ",
  4132. ccedil: "ç",
  4133. egrave: "è",
  4134. eacute: "é",
  4135. ecirc: "ê",
  4136. euml: "ë",
  4137. igrave: "ì",
  4138. iacute: "í",
  4139. icirc: "î",
  4140. iuml: "ï",
  4141. eth: "ð",
  4142. ntilde: "ñ",
  4143. ograve: "ò",
  4144. oacute: "ó",
  4145. ocirc: "ô",
  4146. otilde: "õ",
  4147. ouml: "ö",
  4148. oslash: "ø",
  4149. ugrave: "ù",
  4150. uacute: "ú",
  4151. ucirc: "û",
  4152. uuml: "ü",
  4153. yacute: "ý",
  4154. thorn: "þ",
  4155. yuml: "ÿ",
  4156. nbsp: "\u00a0",
  4157. iexcl: "¡",
  4158. cent: "¢",
  4159. pound: "£",
  4160. curren: "¤",
  4161. yen: "¥",
  4162. brvbar: "¦",
  4163. sect: "§",
  4164. uml: "¨",
  4165. copy: "©",
  4166. ordf: "ª",
  4167. laquo: "«",
  4168. not: "¬",
  4169. shy: "­­",
  4170. reg: "®",
  4171. macr: "¯",
  4172. deg: "°",
  4173. plusmn: "±",
  4174. sup2: "²",
  4175. sup3: "³",
  4176. acute: "´",
  4177. micro: "µ",
  4178. para: "¶",
  4179. middot: "·",
  4180. cedil: "¸",
  4181. sup1: "¹",
  4182. ordm: "º",
  4183. raquo: "»",
  4184. frac14: "¼",
  4185. frac12: "½",
  4186. frac34: "¾",
  4187. iquest: "¿",
  4188. times: "×",
  4189. divide: "÷",
  4190. forall: "∀",
  4191. part: "∂",
  4192. exist: "∃",
  4193. empty: "∅",
  4194. nabla: "∇",
  4195. isin: "∈",
  4196. notin: "∉",
  4197. ni: "∋",
  4198. prod: "∏",
  4199. sum: "∑",
  4200. minus: "−",
  4201. lowast: "∗",
  4202. radic: "√",
  4203. prop: "∝",
  4204. infin: "∞",
  4205. ang: "∠",
  4206. and: "∧",
  4207. or: "∨",
  4208. cap: "∩",
  4209. cup: "∪",
  4210. 'int': "∫",
  4211. there4: "∴",
  4212. sim: "∼",
  4213. cong: "≅",
  4214. asymp: "≈",
  4215. ne: "≠",
  4216. equiv: "≡",
  4217. le: "≤",
  4218. ge: "≥",
  4219. sub: "⊂",
  4220. sup: "⊃",
  4221. nsub: "⊄",
  4222. sube: "⊆",
  4223. supe: "⊇",
  4224. oplus: "⊕",
  4225. otimes: "⊗",
  4226. perp: "⊥",
  4227. sdot: "⋅",
  4228. Alpha: "Α",
  4229. Beta: "Β",
  4230. Gamma: "Γ",
  4231. Delta: "Δ",
  4232. Epsilon: "Ε",
  4233. Zeta: "Ζ",
  4234. Eta: "Η",
  4235. Theta: "Θ",
  4236. Iota: "Ι",
  4237. Kappa: "Κ",
  4238. Lambda: "Λ",
  4239. Mu: "Μ",
  4240. Nu: "Ν",
  4241. Xi: "Ξ",
  4242. Omicron: "Ο",
  4243. Pi: "Π",
  4244. Rho: "Ρ",
  4245. Sigma: "Σ",
  4246. Tau: "Τ",
  4247. Upsilon: "Υ",
  4248. Phi: "Φ",
  4249. Chi: "Χ",
  4250. Psi: "Ψ",
  4251. Omega: "Ω",
  4252. alpha: "α",
  4253. beta: "β",
  4254. gamma: "γ",
  4255. delta: "δ",
  4256. epsilon: "ε",
  4257. zeta: "ζ",
  4258. eta: "η",
  4259. theta: "θ",
  4260. iota: "ι",
  4261. kappa: "κ",
  4262. lambda: "λ",
  4263. mu: "μ",
  4264. nu: "ν",
  4265. xi: "ξ",
  4266. omicron: "ο",
  4267. pi: "π",
  4268. rho: "ρ",
  4269. sigmaf: "ς",
  4270. sigma: "σ",
  4271. tau: "τ",
  4272. upsilon: "υ",
  4273. phi: "φ",
  4274. chi: "χ",
  4275. psi: "ψ",
  4276. omega: "ω",
  4277. thetasym: "ϑ",
  4278. upsih: "ϒ",
  4279. piv: "ϖ",
  4280. OElig: "Œ",
  4281. oelig: "œ",
  4282. Scaron: "Š",
  4283. scaron: "š",
  4284. Yuml: "Ÿ",
  4285. fnof: "ƒ",
  4286. circ: "ˆ",
  4287. tilde: "˜",
  4288. ensp: " ",
  4289. emsp: " ",
  4290. thinsp: " ",
  4291. zwnj: "‌",
  4292. zwj: "‍",
  4293. lrm: "‎",
  4294. rlm: "‏",
  4295. ndash: "–",
  4296. mdash: "—",
  4297. lsquo: "‘",
  4298. rsquo: "’",
  4299. sbquo: "‚",
  4300. ldquo: "“",
  4301. rdquo: "”",
  4302. bdquo: "„",
  4303. dagger: "†",
  4304. Dagger: "‡",
  4305. bull: "•",
  4306. hellip: "…",
  4307. permil: "‰",
  4308. prime: "′",
  4309. Prime: "″",
  4310. lsaquo: "‹",
  4311. rsaquo: "›",
  4312. oline: "‾",
  4313. euro: "€",
  4314. trade: "™",
  4315. larr: "←",
  4316. uarr: "↑",
  4317. rarr: "→",
  4318. darr: "↓",
  4319. harr: "↔",
  4320. crarr: "↵",
  4321. lceil: "⌈",
  4322. rceil: "⌉",
  4323. lfloor: "⌊",
  4324. rfloor: "⌋",
  4325. loz: "◊",
  4326. spades: "♠",
  4327. clubs: "♣",
  4328. hearts: "♥",
  4329. diams: "♦"
  4330. });
  4331. /**
  4332. * @deprecated use `HTML_ENTITIES` instead
  4333. * @see HTML_ENTITIES
  4334. */
  4335. exports.entityMap = exports.HTML_ENTITIES
  4336. /***/ }),
  4337. /* 16 */
  4338. /***/ (function(module, exports, __webpack_require__) {
  4339. var NAMESPACE = __webpack_require__(1).NAMESPACE;
  4340. //[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
  4341. //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
  4342. //[5] Name ::= NameStartChar (NameChar)*
  4343. var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
  4344. var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
  4345. var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
  4346. //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
  4347. //var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
  4348. //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
  4349. //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
  4350. var S_TAG = 0;//tag name offerring
  4351. var S_ATTR = 1;//attr name offerring
  4352. var S_ATTR_SPACE=2;//attr name end and space offer
  4353. var S_EQ = 3;//=space?
  4354. var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
  4355. var S_ATTR_END = 5;//attr value end and no space(quot end)
  4356. var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
  4357. var S_TAG_CLOSE = 7;//closed el<el />
  4358. /**
  4359. * Creates an error that will not be caught by XMLReader aka the SAX parser.
  4360. *
  4361. * @param {string} message
  4362. * @param {any?} locator Optional, can provide details about the location in the source
  4363. * @constructor
  4364. */
  4365. function ParseError(message, locator) {
  4366. this.message = message
  4367. this.locator = locator
  4368. if(Error.captureStackTrace) Error.captureStackTrace(this, ParseError);
  4369. }
  4370. ParseError.prototype = new Error();
  4371. ParseError.prototype.name = ParseError.name
  4372. function XMLReader(){
  4373. }
  4374. XMLReader.prototype = {
  4375. parse:function(source,defaultNSMap,entityMap){
  4376. var domBuilder = this.domBuilder;
  4377. domBuilder.startDocument();
  4378. _copy(defaultNSMap ,defaultNSMap = {})
  4379. parse(source,defaultNSMap,entityMap,
  4380. domBuilder,this.errorHandler);
  4381. domBuilder.endDocument();
  4382. }
  4383. }
  4384. function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
  4385. function fixedFromCharCode(code) {
  4386. // String.prototype.fromCharCode does not supports
  4387. // > 2 bytes unicode chars directly
  4388. if (code > 0xffff) {
  4389. code -= 0x10000;
  4390. var surrogate1 = 0xd800 + (code >> 10)
  4391. , surrogate2 = 0xdc00 + (code & 0x3ff);
  4392. return String.fromCharCode(surrogate1, surrogate2);
  4393. } else {
  4394. return String.fromCharCode(code);
  4395. }
  4396. }
  4397. function entityReplacer(a){
  4398. var k = a.slice(1,-1);
  4399. if (Object.hasOwnProperty.call(entityMap, k)) {
  4400. return entityMap[k];
  4401. }else if(k.charAt(0) === '#'){
  4402. return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
  4403. }else{
  4404. errorHandler.error('entity not found:'+a);
  4405. return a;
  4406. }
  4407. }
  4408. function appendText(end){//has some bugs
  4409. if(end>start){
  4410. var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
  4411. locator&&position(start);
  4412. domBuilder.characters(xt,0,end-start);
  4413. start = end
  4414. }
  4415. }
  4416. function position(p,m){
  4417. while(p>=lineEnd && (m = linePattern.exec(source))){
  4418. lineStart = m.index;
  4419. lineEnd = lineStart + m[0].length;
  4420. locator.lineNumber++;
  4421. //console.log('line++:',locator,startPos,endPos)
  4422. }
  4423. locator.columnNumber = p-lineStart+1;
  4424. }
  4425. var lineStart = 0;
  4426. var lineEnd = 0;
  4427. var linePattern = /.*(?:\r\n?|\n)|.*$/g
  4428. var locator = domBuilder.locator;
  4429. var parseStack = [{currentNSMap:defaultNSMapCopy}]
  4430. var closeMap = {};
  4431. var start = 0;
  4432. while(true){
  4433. try{
  4434. var tagStart = source.indexOf('<',start);
  4435. if(tagStart<0){
  4436. if(!source.substr(start).match(/^\s*$/)){
  4437. var doc = domBuilder.doc;
  4438. var text = doc.createTextNode(source.substr(start));
  4439. doc.appendChild(text);
  4440. domBuilder.currentElement = text;
  4441. }
  4442. return;
  4443. }
  4444. if(tagStart>start){
  4445. appendText(tagStart);
  4446. }
  4447. switch(source.charAt(tagStart+1)){
  4448. case '/':
  4449. var end = source.indexOf('>',tagStart+3);
  4450. var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, '');
  4451. var config = parseStack.pop();
  4452. if(end<0){
  4453. tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
  4454. errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
  4455. end = tagStart+1+tagName.length;
  4456. }else if(tagName.match(/\s</)){
  4457. tagName = tagName.replace(/[\s<].*/,'');
  4458. errorHandler.error("end tag name: "+tagName+' maybe not complete');
  4459. end = tagStart+1+tagName.length;
  4460. }
  4461. var localNSMap = config.localNSMap;
  4462. var endMatch = config.tagName == tagName;
  4463. var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase()
  4464. if(endIgnoreCaseMach){
  4465. domBuilder.endElement(config.uri,config.localName,tagName);
  4466. if(localNSMap){
  4467. for(var prefix in localNSMap){
  4468. domBuilder.endPrefixMapping(prefix) ;
  4469. }
  4470. }
  4471. if(!endMatch){
  4472. errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName ); // No known test case
  4473. }
  4474. }else{
  4475. parseStack.push(config)
  4476. }
  4477. end++;
  4478. break;
  4479. // end elment
  4480. case '?':// <?...?>
  4481. locator&&position(tagStart);
  4482. end = parseInstruction(source,tagStart,domBuilder);
  4483. break;
  4484. case '!':// <!doctype,<![CDATA,<!--
  4485. locator&&position(tagStart);
  4486. end = parseDCC(source,tagStart,domBuilder,errorHandler);
  4487. break;
  4488. default:
  4489. locator&&position(tagStart);
  4490. var el = new ElementAttributes();
  4491. var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
  4492. //elStartEnd
  4493. var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
  4494. var len = el.length;
  4495. if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
  4496. el.closed = true;
  4497. if(!entityMap.nbsp){
  4498. errorHandler.warning('unclosed xml attribute');
  4499. }
  4500. }
  4501. if(locator && len){
  4502. var locator2 = copyLocator(locator,{});
  4503. //try{//attribute position fixed
  4504. for(var i = 0;i<len;i++){
  4505. var a = el[i];
  4506. position(a.offset);
  4507. a.locator = copyLocator(locator,{});
  4508. }
  4509. domBuilder.locator = locator2
  4510. if(appendElement(el,domBuilder,currentNSMap)){
  4511. parseStack.push(el)
  4512. }
  4513. domBuilder.locator = locator;
  4514. }else{
  4515. if(appendElement(el,domBuilder,currentNSMap)){
  4516. parseStack.push(el)
  4517. }
  4518. }
  4519. if (NAMESPACE.isHTML(el.uri) && !el.closed) {
  4520. end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
  4521. } else {
  4522. end++;
  4523. }
  4524. }
  4525. }catch(e){
  4526. if (e instanceof ParseError) {
  4527. throw e;
  4528. }
  4529. errorHandler.error('element parse error: '+e)
  4530. end = -1;
  4531. }
  4532. if(end>start){
  4533. start = end;
  4534. }else{
  4535. //TODO: 这里有可能sax回退,有位置错误风险
  4536. appendText(Math.max(tagStart,start)+1);
  4537. }
  4538. }
  4539. }
  4540. function copyLocator(f,t){
  4541. t.lineNumber = f.lineNumber;
  4542. t.columnNumber = f.columnNumber;
  4543. return t;
  4544. }
  4545. /**
  4546. * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
  4547. * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
  4548. */
  4549. function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
  4550. /**
  4551. * @param {string} qname
  4552. * @param {string} value
  4553. * @param {number} startIndex
  4554. */
  4555. function addAttribute(qname, value, startIndex) {
  4556. if (el.attributeNames.hasOwnProperty(qname)) {
  4557. errorHandler.fatalError('Attribute ' + qname + ' redefined')
  4558. }
  4559. el.addValue(
  4560. qname,
  4561. // @see https://www.w3.org/TR/xml/#AVNormalize
  4562. // since the xmldom sax parser does not "interpret" DTD the following is not implemented:
  4563. // - recursive replacement of (DTD) entity references
  4564. // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA
  4565. value.replace(/[\t\n\r]/g, ' ').replace(/&#?\w+;/g, entityReplacer),
  4566. startIndex
  4567. )
  4568. }
  4569. var attrName;
  4570. var value;
  4571. var p = ++start;
  4572. var s = S_TAG;//status
  4573. while(true){
  4574. var c = source.charAt(p);
  4575. switch(c){
  4576. case '=':
  4577. if(s === S_ATTR){//attrName
  4578. attrName = source.slice(start,p);
  4579. s = S_EQ;
  4580. }else if(s === S_ATTR_SPACE){
  4581. s = S_EQ;
  4582. }else{
  4583. //fatalError: equal must after attrName or space after attrName
  4584. throw new Error('attribute equal must after attrName'); // No known test case
  4585. }
  4586. break;
  4587. case '\'':
  4588. case '"':
  4589. if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
  4590. ){//equal
  4591. if(s === S_ATTR){
  4592. errorHandler.warning('attribute value must after "="')
  4593. attrName = source.slice(start,p)
  4594. }
  4595. start = p+1;
  4596. p = source.indexOf(c,start)
  4597. if(p>0){
  4598. value = source.slice(start, p);
  4599. addAttribute(attrName, value, start-1);
  4600. s = S_ATTR_END;
  4601. }else{
  4602. //fatalError: no end quot match
  4603. throw new Error('attribute value no end \''+c+'\' match');
  4604. }
  4605. }else if(s == S_ATTR_NOQUOT_VALUE){
  4606. value = source.slice(start, p);
  4607. addAttribute(attrName, value, start);
  4608. errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
  4609. start = p+1;
  4610. s = S_ATTR_END
  4611. }else{
  4612. //fatalError: no equal before
  4613. throw new Error('attribute value must after "="'); // No known test case
  4614. }
  4615. break;
  4616. case '/':
  4617. switch(s){
  4618. case S_TAG:
  4619. el.setTagName(source.slice(start,p));
  4620. case S_ATTR_END:
  4621. case S_TAG_SPACE:
  4622. case S_TAG_CLOSE:
  4623. s =S_TAG_CLOSE;
  4624. el.closed = true;
  4625. case S_ATTR_NOQUOT_VALUE:
  4626. case S_ATTR:
  4627. case S_ATTR_SPACE:
  4628. break;
  4629. //case S_EQ:
  4630. default:
  4631. throw new Error("attribute invalid close char('/')") // No known test case
  4632. }
  4633. break;
  4634. case ''://end document
  4635. errorHandler.error('unexpected end of input');
  4636. if(s == S_TAG){
  4637. el.setTagName(source.slice(start,p));
  4638. }
  4639. return p;
  4640. case '>':
  4641. switch(s){
  4642. case S_TAG:
  4643. el.setTagName(source.slice(start,p));
  4644. case S_ATTR_END:
  4645. case S_TAG_SPACE:
  4646. case S_TAG_CLOSE:
  4647. break;//normal
  4648. case S_ATTR_NOQUOT_VALUE://Compatible state
  4649. case S_ATTR:
  4650. value = source.slice(start,p);
  4651. if(value.slice(-1) === '/'){
  4652. el.closed = true;
  4653. value = value.slice(0,-1)
  4654. }
  4655. case S_ATTR_SPACE:
  4656. if(s === S_ATTR_SPACE){
  4657. value = attrName;
  4658. }
  4659. if(s == S_ATTR_NOQUOT_VALUE){
  4660. errorHandler.warning('attribute "'+value+'" missed quot(")!');
  4661. addAttribute(attrName, value, start)
  4662. }else{
  4663. if(!NAMESPACE.isHTML(currentNSMap['']) || !value.match(/^(?:disabled|checked|selected)$/i)){
  4664. errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
  4665. }
  4666. addAttribute(value, value, start)
  4667. }
  4668. break;
  4669. case S_EQ:
  4670. throw new Error('attribute value missed!!');
  4671. }
  4672. // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
  4673. return p;
  4674. /*xml space '\x20' | #x9 | #xD | #xA; */
  4675. case '\u0080':
  4676. c = ' ';
  4677. default:
  4678. if(c<= ' '){//space
  4679. switch(s){
  4680. case S_TAG:
  4681. el.setTagName(source.slice(start,p));//tagName
  4682. s = S_TAG_SPACE;
  4683. break;
  4684. case S_ATTR:
  4685. attrName = source.slice(start,p)
  4686. s = S_ATTR_SPACE;
  4687. break;
  4688. case S_ATTR_NOQUOT_VALUE:
  4689. var value = source.slice(start, p);
  4690. errorHandler.warning('attribute "'+value+'" missed quot(")!!');
  4691. addAttribute(attrName, value, start)
  4692. case S_ATTR_END:
  4693. s = S_TAG_SPACE;
  4694. break;
  4695. //case S_TAG_SPACE:
  4696. //case S_EQ:
  4697. //case S_ATTR_SPACE:
  4698. // void();break;
  4699. //case S_TAG_CLOSE:
  4700. //ignore warning
  4701. }
  4702. }else{//not space
  4703. //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
  4704. //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
  4705. switch(s){
  4706. //case S_TAG:void();break;
  4707. //case S_ATTR:void();break;
  4708. //case S_ATTR_NOQUOT_VALUE:void();break;
  4709. case S_ATTR_SPACE:
  4710. var tagName = el.tagName;
  4711. if (!NAMESPACE.isHTML(currentNSMap['']) || !attrName.match(/^(?:disabled|checked|selected)$/i)) {
  4712. errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!')
  4713. }
  4714. addAttribute(attrName, attrName, start);
  4715. start = p;
  4716. s = S_ATTR;
  4717. break;
  4718. case S_ATTR_END:
  4719. errorHandler.warning('attribute space is required"'+attrName+'"!!')
  4720. case S_TAG_SPACE:
  4721. s = S_ATTR;
  4722. start = p;
  4723. break;
  4724. case S_EQ:
  4725. s = S_ATTR_NOQUOT_VALUE;
  4726. start = p;
  4727. break;
  4728. case S_TAG_CLOSE:
  4729. throw new Error("elements closed character '/' and '>' must be connected to");
  4730. }
  4731. }
  4732. }//end outer switch
  4733. //console.log('p++',p)
  4734. p++;
  4735. }
  4736. }
  4737. /**
  4738. * @return true if has new namespace define
  4739. */
  4740. function appendElement(el,domBuilder,currentNSMap){
  4741. var tagName = el.tagName;
  4742. var localNSMap = null;
  4743. //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
  4744. var i = el.length;
  4745. while(i--){
  4746. var a = el[i];
  4747. var qName = a.qName;
  4748. var value = a.value;
  4749. var nsp = qName.indexOf(':');
  4750. if(nsp>0){
  4751. var prefix = a.prefix = qName.slice(0,nsp);
  4752. var localName = qName.slice(nsp+1);
  4753. var nsPrefix = prefix === 'xmlns' && localName
  4754. }else{
  4755. localName = qName;
  4756. prefix = null
  4757. nsPrefix = qName === 'xmlns' && ''
  4758. }
  4759. //can not set prefix,because prefix !== ''
  4760. a.localName = localName ;
  4761. //prefix == null for no ns prefix attribute
  4762. if(nsPrefix !== false){//hack!!
  4763. if(localNSMap == null){
  4764. localNSMap = {}
  4765. //console.log(currentNSMap,0)
  4766. _copy(currentNSMap,currentNSMap={})
  4767. //console.log(currentNSMap,1)
  4768. }
  4769. currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
  4770. a.uri = NAMESPACE.XMLNS
  4771. domBuilder.startPrefixMapping(nsPrefix, value)
  4772. }
  4773. }
  4774. var i = el.length;
  4775. while(i--){
  4776. a = el[i];
  4777. var prefix = a.prefix;
  4778. if(prefix){//no prefix attribute has no namespace
  4779. if(prefix === 'xml'){
  4780. a.uri = NAMESPACE.XML;
  4781. }if(prefix !== 'xmlns'){
  4782. a.uri = currentNSMap[prefix || '']
  4783. //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
  4784. }
  4785. }
  4786. }
  4787. var nsp = tagName.indexOf(':');
  4788. if(nsp>0){
  4789. prefix = el.prefix = tagName.slice(0,nsp);
  4790. localName = el.localName = tagName.slice(nsp+1);
  4791. }else{
  4792. prefix = null;//important!!
  4793. localName = el.localName = tagName;
  4794. }
  4795. //no prefix element has default namespace
  4796. var ns = el.uri = currentNSMap[prefix || ''];
  4797. domBuilder.startElement(ns,localName,tagName,el);
  4798. //endPrefixMapping and startPrefixMapping have not any help for dom builder
  4799. //localNSMap = null
  4800. if(el.closed){
  4801. domBuilder.endElement(ns,localName,tagName);
  4802. if(localNSMap){
  4803. for(prefix in localNSMap){
  4804. domBuilder.endPrefixMapping(prefix)
  4805. }
  4806. }
  4807. }else{
  4808. el.currentNSMap = currentNSMap;
  4809. el.localNSMap = localNSMap;
  4810. //parseStack.push(el);
  4811. return true;
  4812. }
  4813. }
  4814. function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
  4815. if(/^(?:script|textarea)$/i.test(tagName)){
  4816. var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
  4817. var text = source.substring(elStartEnd+1,elEndStart);
  4818. if(/[&<]/.test(text)){
  4819. if(/^script$/i.test(tagName)){
  4820. //if(!/\]\]>/.test(text)){
  4821. //lexHandler.startCDATA();
  4822. domBuilder.characters(text,0,text.length);
  4823. //lexHandler.endCDATA();
  4824. return elEndStart;
  4825. //}
  4826. }//}else{//text area
  4827. text = text.replace(/&#?\w+;/g,entityReplacer);
  4828. domBuilder.characters(text,0,text.length);
  4829. return elEndStart;
  4830. //}
  4831. }
  4832. }
  4833. return elStartEnd+1;
  4834. }
  4835. function fixSelfClosed(source,elStartEnd,tagName,closeMap){
  4836. //if(tagName in closeMap){
  4837. var pos = closeMap[tagName];
  4838. if(pos == null){
  4839. //console.log(tagName)
  4840. pos = source.lastIndexOf('</'+tagName+'>')
  4841. if(pos<elStartEnd){//忘记闭合
  4842. pos = source.lastIndexOf('</'+tagName)
  4843. }
  4844. closeMap[tagName] =pos
  4845. }
  4846. return pos<elStartEnd;
  4847. //}
  4848. }
  4849. function _copy(source,target){
  4850. for(var n in source){target[n] = source[n]}
  4851. }
  4852. function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
  4853. var next= source.charAt(start+2)
  4854. switch(next){
  4855. case '-':
  4856. if(source.charAt(start + 3) === '-'){
  4857. var end = source.indexOf('-->',start+4);
  4858. //append comment source.substring(4,end)//<!--
  4859. if(end>start){
  4860. domBuilder.comment(source,start+4,end-start-4);
  4861. return end+3;
  4862. }else{
  4863. errorHandler.error("Unclosed comment");
  4864. return -1;
  4865. }
  4866. }else{
  4867. //error
  4868. return -1;
  4869. }
  4870. default:
  4871. if(source.substr(start+3,6) == 'CDATA['){
  4872. var end = source.indexOf(']]>',start+9);
  4873. domBuilder.startCDATA();
  4874. domBuilder.characters(source,start+9,end-start-9);
  4875. domBuilder.endCDATA()
  4876. return end+3;
  4877. }
  4878. //<!DOCTYPE
  4879. //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
  4880. var matchs = split(source,start);
  4881. var len = matchs.length;
  4882. if(len>1 && /!doctype/i.test(matchs[0][0])){
  4883. var name = matchs[1][0];
  4884. var pubid = false;
  4885. var sysid = false;
  4886. if(len>3){
  4887. if(/^public$/i.test(matchs[2][0])){
  4888. pubid = matchs[3][0];
  4889. sysid = len>4 && matchs[4][0];
  4890. }else if(/^system$/i.test(matchs[2][0])){
  4891. sysid = matchs[3][0];
  4892. }
  4893. }
  4894. var lastMatch = matchs[len-1]
  4895. domBuilder.startDTD(name, pubid, sysid);
  4896. domBuilder.endDTD();
  4897. return lastMatch.index+lastMatch[0].length
  4898. }
  4899. }
  4900. return -1;
  4901. }
  4902. function parseInstruction(source,start,domBuilder){
  4903. var end = source.indexOf('?>',start);
  4904. if(end){
  4905. var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
  4906. if(match){
  4907. var len = match[0].length;
  4908. domBuilder.processingInstruction(match[1], match[2]) ;
  4909. return end+2;
  4910. }else{//error
  4911. return -1;
  4912. }
  4913. }
  4914. return -1;
  4915. }
  4916. function ElementAttributes(){
  4917. this.attributeNames = {}
  4918. }
  4919. ElementAttributes.prototype = {
  4920. setTagName:function(tagName){
  4921. if(!tagNamePattern.test(tagName)){
  4922. throw new Error('invalid tagName:'+tagName)
  4923. }
  4924. this.tagName = tagName
  4925. },
  4926. addValue:function(qName, value, offset) {
  4927. if(!tagNamePattern.test(qName)){
  4928. throw new Error('invalid attribute:'+qName)
  4929. }
  4930. this.attributeNames[qName] = this.length;
  4931. this[this.length++] = {qName:qName,value:value,offset:offset}
  4932. },
  4933. length:0,
  4934. getLocalName:function(i){return this[i].localName},
  4935. getLocator:function(i){return this[i].locator},
  4936. getQName:function(i){return this[i].qName},
  4937. getURI:function(i){return this[i].uri},
  4938. getValue:function(i){return this[i].value}
  4939. // ,getIndex:function(uri, localName)){
  4940. // if(localName){
  4941. //
  4942. // }else{
  4943. // var qName = uri
  4944. // }
  4945. // },
  4946. // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
  4947. // getType:function(uri,localName){}
  4948. // getType:function(i){},
  4949. }
  4950. function split(source,start){
  4951. var match;
  4952. var buf = [];
  4953. var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
  4954. reg.lastIndex = start;
  4955. reg.exec(source);//skip <
  4956. while(match = reg.exec(source)){
  4957. buf.push(match);
  4958. if(match[1])return buf;
  4959. }
  4960. }
  4961. exports.XMLReader = XMLReader;
  4962. exports.ParseError = ParseError;
  4963. /***/ }),
  4964. /* 17 */
  4965. /***/ (function(module, exports) {
  4966. //copyright Ryan Day 2010 <http://ryanday.org>, Joscha Feth 2013 <http://www.feth.com> [MIT Licensed]
  4967. var element_start_char = "a-zA-Z_\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FFF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
  4968. var element_non_start_char = "\-.0-9\u00B7\u0300-\u036F\u203F\u2040";
  4969. var element_replace = new RegExp("^([^" + element_start_char + "])|^((x|X)(m|M)(l|L))|([^" + element_start_char + element_non_start_char + "])", "g");
  4970. var not_safe_in_xml = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm;
  4971. var objKeys = function (obj) {
  4972. var l = [];
  4973. if (obj instanceof Object) {
  4974. for (var k in obj) {
  4975. if (obj.hasOwnProperty(k)) {
  4976. l.push(k);
  4977. }
  4978. }
  4979. }
  4980. return l;
  4981. };
  4982. var process_to_xml = function (node_data, options) {
  4983. var makeNode = function (name, content, attributes, level, hasSubNodes) {
  4984. var indent_value = options.indent !== undefined ? options.indent : "\t";
  4985. var indent = options.prettyPrint ? '\n' + new Array(level).join(indent_value) : '';
  4986. if (options.removeIllegalNameCharacters) {
  4987. name = name.replace(element_replace, '_');
  4988. }
  4989. var node = [indent, '<', name, attributes || ''];
  4990. if (content && content.length > 0) {
  4991. node.push('>');
  4992. node.push(content);
  4993. hasSubNodes && node.push(indent);
  4994. node.push('</');
  4995. node.push(name);
  4996. node.push('>');
  4997. } else {
  4998. node.push('/>');
  4999. }
  5000. return node.join('');
  5001. };
  5002. return function fn(node_data, node_descriptor, level) {
  5003. var type = typeof node_data;
  5004. if (Array.isArray ? Array.isArray(node_data) : node_data instanceof Array) {
  5005. type = 'array';
  5006. } else if (node_data instanceof Date) {
  5007. type = 'date';
  5008. }
  5009. switch (type) {
  5010. //if value is an array create child nodes from values
  5011. case 'array':
  5012. var ret = [];
  5013. node_data.map(function (v) {
  5014. ret.push(fn(v, 1, level + 1));
  5015. //entries that are values of an array are the only ones that can be special node descriptors
  5016. });
  5017. options.prettyPrint && ret.push('\n');
  5018. return ret.join('');
  5019. break;
  5020. case 'date':
  5021. // cast dates to ISO 8601 date (soap likes it)
  5022. return node_data.toJSON ? node_data.toJSON() : node_data + '';
  5023. break;
  5024. case 'object':
  5025. var nodes = [];
  5026. for (var name in node_data) {
  5027. if (node_data.hasOwnProperty(name)) {
  5028. if (node_data[name] instanceof Array) {
  5029. for (var j = 0; j < node_data[name].length; j++) {
  5030. if (node_data[name].hasOwnProperty(j)) {
  5031. nodes.push(makeNode(name, fn(node_data[name][j], 0, level + 1), null, level + 1, objKeys(node_data[name][j]).length));
  5032. }
  5033. }
  5034. } else {
  5035. nodes.push(makeNode(name, fn(node_data[name], 0, level + 1), null, level + 1));
  5036. }
  5037. }
  5038. }
  5039. options.prettyPrint && nodes.length > 0 && nodes.push('\n');
  5040. return nodes.join('');
  5041. break;
  5042. case 'function':
  5043. return node_data();
  5044. break;
  5045. default:
  5046. return options.escape ? esc(node_data) : '' + node_data;
  5047. }
  5048. }(node_data, 0, 0);
  5049. };
  5050. var xml_header = function (standalone) {
  5051. var ret = ['<?xml version="1.0" encoding="UTF-8"'];
  5052. if (standalone) {
  5053. ret.push(' standalone="yes"');
  5054. }
  5055. ret.push('?>');
  5056. return ret.join('');
  5057. };
  5058. function esc(str) {
  5059. return ('' + str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&apos;').replace(/"/g, '&quot;').replace(not_safe_in_xml, '');
  5060. }
  5061. module.exports = function (obj, options) {
  5062. if (!options) {
  5063. options = {
  5064. xmlHeader: {
  5065. standalone: true
  5066. },
  5067. prettyPrint: true,
  5068. indent: " ",
  5069. escape: true
  5070. };
  5071. }
  5072. if (typeof obj == 'string') {
  5073. try {
  5074. obj = JSON.parse(obj.toString());
  5075. } catch (e) {
  5076. return false;
  5077. }
  5078. }
  5079. var xmlheader = '';
  5080. var docType = '';
  5081. if (options) {
  5082. if (typeof options == 'object') {
  5083. // our config is an object
  5084. if (options.xmlHeader) {
  5085. // the user wants an xml header
  5086. xmlheader = xml_header(!!options.xmlHeader.standalone);
  5087. }
  5088. if (typeof options.docType != 'undefined') {
  5089. docType = '<!DOCTYPE ' + options.docType + '>';
  5090. }
  5091. } else {
  5092. // our config is a boolean value, so just add xml header
  5093. xmlheader = xml_header();
  5094. }
  5095. }
  5096. options = options || {};
  5097. var ret = [xmlheader, options.prettyPrint && docType ? '\n' : '', docType, process_to_xml(obj, options)];
  5098. return ret.join('').replace(/\n{2,}/g, '\n').replace(/\s+$/g, '');
  5099. };
  5100. /***/ }),
  5101. /* 18 */
  5102. /***/ (function(module, exports, __webpack_require__) {
  5103. var session = __webpack_require__(5);
  5104. var util = __webpack_require__(0);
  5105. var originApiMap = {};
  5106. var transferToTaskMethod = function (apiMap, apiName) {
  5107. originApiMap[apiName] = apiMap[apiName];
  5108. apiMap[apiName] = function (params, callback) {
  5109. if (params.SkipTask) {
  5110. originApiMap[apiName].call(this, params, callback);
  5111. } else {
  5112. this._addTask(apiName, params, callback);
  5113. }
  5114. };
  5115. };
  5116. var initTask = function (cos) {
  5117. var queue = [];
  5118. var tasks = {};
  5119. var uploadingFileCount = 0;
  5120. var nextUploadIndex = 0;
  5121. // 接口返回简略的任务信息
  5122. var formatTask = function (task) {
  5123. var t = {
  5124. id: task.id,
  5125. Bucket: task.Bucket,
  5126. Region: task.Region,
  5127. Key: task.Key,
  5128. FilePath: task.FilePath,
  5129. state: task.state,
  5130. loaded: task.loaded,
  5131. size: task.size,
  5132. speed: task.speed,
  5133. percent: task.percent,
  5134. hashPercent: task.hashPercent,
  5135. error: task.error
  5136. };
  5137. if (task.FilePath) t.FilePath = task.FilePath;
  5138. if (task._custom) t._custom = task._custom; // 控制台使用
  5139. return t;
  5140. };
  5141. var emitListUpdate = function () {
  5142. var timer;
  5143. var emit = function () {
  5144. timer = 0;
  5145. cos.emit('task-list-update', { list: util.map(queue, formatTask) });
  5146. cos.emit('list-update', { list: util.map(queue, formatTask) });
  5147. };
  5148. return function () {
  5149. if (!timer) timer = setTimeout(emit);
  5150. };
  5151. }();
  5152. var clearQueue = function () {
  5153. if (queue.length <= cos.options.UploadQueueSize) return;
  5154. for (var i = 0; i < nextUploadIndex && // 小于当前操作的 index 才清理
  5155. i < queue.length && // 大于队列才清理
  5156. queue.length > cos.options.UploadQueueSize // 如果还太多,才继续清理
  5157. ;) {
  5158. var isActive = queue[i].state === 'waiting' || queue[i].state === 'checking' || queue[i].state === 'uploading';
  5159. if (!queue[i] || !isActive) {
  5160. tasks[queue[i].id] && delete tasks[queue[i].id];
  5161. queue.splice(i, 1);
  5162. nextUploadIndex--;
  5163. } else {
  5164. i++;
  5165. }
  5166. }
  5167. emitListUpdate();
  5168. };
  5169. var startNextTask = function () {
  5170. // 检查是否允许增加执行进程
  5171. if (uploadingFileCount >= cos.options.FileParallelLimit) return;
  5172. // 跳过不可执行的任务
  5173. while (queue[nextUploadIndex] && queue[nextUploadIndex].state !== 'waiting') nextUploadIndex++;
  5174. // 检查是否已遍历结束
  5175. if (nextUploadIndex >= queue.length) return;
  5176. // 上传该遍历到的任务
  5177. var task = queue[nextUploadIndex];
  5178. nextUploadIndex++;
  5179. uploadingFileCount++;
  5180. task.state = 'checking';
  5181. task.params.onTaskStart && task.params.onTaskStart(formatTask(task));
  5182. !task.params.UploadData && (task.params.UploadData = {});
  5183. var apiParams = util.formatParams(task.api, task.params);
  5184. originApiMap[task.api].call(cos, apiParams, function (err, data) {
  5185. if (!cos._isRunningTask(task.id)) return;
  5186. if (task.state === 'checking' || task.state === 'uploading') {
  5187. task.state = err ? 'error' : 'success';
  5188. err && (task.error = err);
  5189. uploadingFileCount--;
  5190. emitListUpdate();
  5191. startNextTask();
  5192. task.callback && task.callback(err, data);
  5193. if (task.state === 'success') {
  5194. if (task.params) {
  5195. delete task.params.UploadData;
  5196. delete task.params.Body;
  5197. delete task.params;
  5198. }
  5199. delete task.callback;
  5200. }
  5201. }
  5202. clearQueue();
  5203. });
  5204. emitListUpdate();
  5205. // 异步执行下一个任务
  5206. setTimeout(startNextTask);
  5207. };
  5208. var killTask = function (id, switchToState) {
  5209. var task = tasks[id];
  5210. if (!task) return;
  5211. var waiting = task && task.state === 'waiting';
  5212. var running = task && (task.state === 'checking' || task.state === 'uploading');
  5213. if (switchToState === 'canceled' && task.state !== 'canceled' || switchToState === 'paused' && waiting || switchToState === 'paused' && running) {
  5214. if (switchToState === 'paused' && task.params.Body && typeof task.params.Body.pipe === 'function') {
  5215. console.error('stream not support pause');
  5216. return;
  5217. }
  5218. task.state = switchToState;
  5219. cos.emit('inner-kill-task', { TaskId: id, toState: switchToState });
  5220. try {
  5221. var UploadId = task && task.params && task.params.UploadData.UploadId;
  5222. } catch (e) {}
  5223. if (switchToState === 'canceled' && UploadId) session.removeUsing(UploadId);
  5224. emitListUpdate();
  5225. if (running) {
  5226. uploadingFileCount--;
  5227. startNextTask();
  5228. }
  5229. if (switchToState === 'canceled') {
  5230. if (task.params) {
  5231. delete task.params.UploadData;
  5232. delete task.params.Body;
  5233. delete task.params;
  5234. }
  5235. delete task.callback;
  5236. }
  5237. }
  5238. clearQueue();
  5239. };
  5240. cos._addTasks = function (taskList) {
  5241. util.each(taskList, function (task) {
  5242. cos._addTask(task.api, task.params, task.callback, true);
  5243. });
  5244. emitListUpdate();
  5245. };
  5246. var isTaskReadyWarning = true;
  5247. cos._addTask = function (api, params, callback, ignoreAddEvent) {
  5248. // 复制参数对象
  5249. params = util.formatParams(api, params);
  5250. // 生成 id
  5251. var id = util.uuid();
  5252. params.TaskId = id;
  5253. params.onTaskReady && params.onTaskReady(id);
  5254. if (params.TaskReady) {
  5255. params.TaskReady(id);
  5256. isTaskReadyWarning && console.warn('warning: Param "TaskReady" has been deprecated. Please use "onTaskReady" instead.');
  5257. isTaskReadyWarning = false;
  5258. }
  5259. var task = {
  5260. // env
  5261. params: params,
  5262. callback: callback,
  5263. api: api,
  5264. index: queue.length,
  5265. // task
  5266. id: id,
  5267. Bucket: params.Bucket,
  5268. Region: params.Region,
  5269. Key: params.Key,
  5270. FilePath: params.FilePath || '',
  5271. state: 'waiting',
  5272. loaded: 0,
  5273. size: 0,
  5274. speed: 0,
  5275. percent: 0,
  5276. hashPercent: 0,
  5277. error: null,
  5278. _custom: params._custom
  5279. };
  5280. var onHashProgress = params.onHashProgress;
  5281. params.onHashProgress = function (info) {
  5282. if (!cos._isRunningTask(task.id)) return;
  5283. task.hashPercent = info.percent;
  5284. onHashProgress && onHashProgress(info);
  5285. emitListUpdate();
  5286. };
  5287. var onProgress = params.onProgress;
  5288. params.onProgress = function (info) {
  5289. if (!cos._isRunningTask(task.id)) return;
  5290. task.state === 'checking' && (task.state = 'uploading');
  5291. task.loaded = info.loaded;
  5292. task.speed = info.speed;
  5293. task.percent = info.percent;
  5294. onProgress && onProgress(info);
  5295. emitListUpdate();
  5296. };
  5297. // 异步获取 filesize
  5298. util.getFileSize(api, params, function (err, size) {
  5299. // 开始处理上传
  5300. if (err) return callback(util.error(err)); // 如果获取大小出错,不加入队列
  5301. // 获取完文件大小再把任务加入队列
  5302. tasks[id] = task;
  5303. queue.push(task);
  5304. task.size = size;
  5305. !ignoreAddEvent && emitListUpdate();
  5306. startNextTask();
  5307. clearQueue();
  5308. });
  5309. return id;
  5310. };
  5311. cos._isRunningTask = function (id) {
  5312. var task = tasks[id];
  5313. return !!(task && (task.state === 'checking' || task.state === 'uploading'));
  5314. };
  5315. cos.getTaskList = function () {
  5316. return util.map(queue, formatTask);
  5317. };
  5318. cos.cancelTask = function (id) {
  5319. killTask(id, 'canceled');
  5320. };
  5321. cos.pauseTask = function (id) {
  5322. killTask(id, 'paused');
  5323. };
  5324. cos.restartTask = function (id) {
  5325. var task = tasks[id];
  5326. if (task && (task.state === 'paused' || task.state === 'error')) {
  5327. task.state = 'waiting';
  5328. emitListUpdate();
  5329. nextUploadIndex = Math.min(nextUploadIndex, task.index);
  5330. startNextTask();
  5331. }
  5332. };
  5333. cos.isUploadRunning = function () {
  5334. return uploadingFileCount || nextUploadIndex < queue.length;
  5335. };
  5336. };
  5337. module.exports.transferToTaskMethod = transferToTaskMethod;
  5338. module.exports.init = initTask;
  5339. /***/ }),
  5340. /* 19 */
  5341. /***/ (function(module, exports, __webpack_require__) {
  5342. var REQUEST = __webpack_require__(20);
  5343. var util = __webpack_require__(0);
  5344. // Bucket 相关
  5345. /**
  5346. * 获取用户的 bucket 列表
  5347. * @param {Object} params 回调函数,必须,下面为参数列表
  5348. * 无特殊参数
  5349. * @param {Function} callback 回调函数,必须
  5350. */
  5351. function getService(params, callback) {
  5352. if (typeof params === 'function') {
  5353. callback = params;
  5354. params = {};
  5355. }
  5356. var protocol = this.options.Protocol || (util.isBrowser && location.protocol === 'http:' ? 'http:' : 'https:');
  5357. var domain = this.options.ServiceDomain;
  5358. var appId = params.AppId || this.options.appId;
  5359. var region = params.Region;
  5360. if (domain) {
  5361. domain = domain.replace(/\{\{AppId\}\}/ig, appId || '').replace(/\{\{Region\}\}/ig, region || '').replace(/\{\{.*?\}\}/ig, '');
  5362. if (!/^[a-zA-Z]+:\/\//.test(domain)) {
  5363. domain = protocol + '//' + domain;
  5364. }
  5365. if (domain.slice(-1) === '/') {
  5366. domain = domain.slice(0, -1);
  5367. }
  5368. } else if (region) {
  5369. domain = protocol + '//cos.' + region + '.myqcloud.com';
  5370. } else {
  5371. domain = protocol + '//service.cos.myqcloud.com';
  5372. }
  5373. var SignHost = '';
  5374. var standardHost = region ? 'cos.' + region + '.myqcloud.com' : 'service.cos.myqcloud.com';
  5375. var urlHost = domain.replace(/^https?:\/\/([^/]+)(\/.*)?$/, '$1');
  5376. if (standardHost === urlHost) SignHost = standardHost;
  5377. submitRequest.call(this, {
  5378. Action: 'name/cos:GetService',
  5379. url: domain,
  5380. method: 'GET',
  5381. headers: params.Headers,
  5382. SignHost: SignHost
  5383. }, function (err, data) {
  5384. if (err) return callback(err);
  5385. var buckets = data && data.ListAllMyBucketsResult && data.ListAllMyBucketsResult.Buckets && data.ListAllMyBucketsResult.Buckets.Bucket || [];
  5386. buckets = util.isArray(buckets) ? buckets : [buckets];
  5387. var owner = data && data.ListAllMyBucketsResult && data.ListAllMyBucketsResult.Owner || {};
  5388. callback(null, {
  5389. Buckets: buckets,
  5390. Owner: owner,
  5391. statusCode: data.statusCode,
  5392. headers: data.headers
  5393. });
  5394. });
  5395. }
  5396. /**
  5397. * 创建 Bucket,并初始化访问权限
  5398. * @param {Object} params 参数对象,必须
  5399. * @param {String} params.Bucket Bucket名称,必须
  5400. * @param {String} params.Region 地域名称,必须
  5401. * @param {String} params.ACL 用户自定义文件权限,可以设置:private,public-read;默认值:private,非必须
  5402. * @param {String} params.GrantRead 赋予被授权者读的权限,格式x-cos-grant-read: uin=" ",uin=" ",非必须
  5403. * @param {String} params.GrantWrite 赋予被授权者写的权限,格式x-cos-grant-write: uin=" ",uin=" ",非必须
  5404. * @param {String} params.GrantFullControl 赋予被授权者读写权限,格式x-cos-grant-full-control: uin=" ",uin=" ",非必须
  5405. * @param {Function} callback 回调函数,必须
  5406. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5407. * @return {Object} data 返回的数据
  5408. * @return {String} data.Location 操作地址
  5409. */
  5410. function putBucket(params, callback) {
  5411. var self = this;
  5412. var xml = '';
  5413. if (params['BucketAZConfig']) {
  5414. var CreateBucketConfiguration = {
  5415. BucketAZConfig: params.BucketAZConfig
  5416. };
  5417. xml = util.json2xml({ CreateBucketConfiguration: CreateBucketConfiguration });
  5418. }
  5419. submitRequest.call(this, {
  5420. Action: 'name/cos:PutBucket',
  5421. method: 'PUT',
  5422. Bucket: params.Bucket,
  5423. Region: params.Region,
  5424. headers: params.Headers,
  5425. body: xml
  5426. }, function (err, data) {
  5427. if (err) return callback(err);
  5428. var url = getUrl({
  5429. protocol: self.options.Protocol,
  5430. domain: self.options.Domain,
  5431. bucket: params.Bucket,
  5432. region: params.Region,
  5433. isLocation: true
  5434. });
  5435. callback(null, {
  5436. Location: url,
  5437. statusCode: data.statusCode,
  5438. headers: data.headers
  5439. });
  5440. });
  5441. }
  5442. /**
  5443. * 查看是否存在该Bucket,是否有权限访问
  5444. * @param {Object} params 参数对象,必须
  5445. * @param {String} params.Bucket Bucket名称,必须
  5446. * @param {String} params.Region 地域名称,必须
  5447. * @param {Function} callback 回调函数,必须
  5448. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5449. * @return {Object} data 返回的数据
  5450. * @return {Boolean} data.BucketExist Bucket是否存在
  5451. * @return {Boolean} data.BucketAuth 是否有 Bucket 的访问权限
  5452. */
  5453. function headBucket(params, callback) {
  5454. submitRequest.call(this, {
  5455. Action: 'name/cos:HeadBucket',
  5456. Bucket: params.Bucket,
  5457. Region: params.Region,
  5458. headers: params.Headers,
  5459. method: 'HEAD'
  5460. }, callback);
  5461. }
  5462. /**
  5463. * 获取 Bucket 下的 object 列表
  5464. * @param {Object} params 参数对象,必须
  5465. * @param {String} params.Bucket Bucket名称,必须
  5466. * @param {String} params.Region 地域名称,必须
  5467. * @param {String} params.Prefix 前缀匹配,用来规定返回的文件前缀地址,非必须
  5468. * @param {String} params.Delimiter 定界符为一个符号,如果有Prefix,则将Prefix到delimiter之间的相同路径归为一类,非必须
  5469. * @param {String} params.Marker 默认以UTF-8二进制顺序列出条目,所有列出条目从marker开始,非必须
  5470. * @param {String} params.MaxKeys 单次返回最大的条目数量,默认1000,非必须
  5471. * @param {String} params.EncodingType 规定返回值的编码方式,非必须
  5472. * @param {Function} callback 回调函数,必须
  5473. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5474. * @return {Object} data 返回的数据
  5475. * @return {Object} data.ListBucketResult 返回的 object 列表信息
  5476. */
  5477. function getBucket(params, callback) {
  5478. var reqParams = {};
  5479. reqParams['prefix'] = params['Prefix'] || '';
  5480. reqParams['delimiter'] = params['Delimiter'];
  5481. reqParams['marker'] = params['Marker'];
  5482. reqParams['max-keys'] = params['MaxKeys'];
  5483. reqParams['encoding-type'] = params['EncodingType'];
  5484. submitRequest.call(this, {
  5485. Action: 'name/cos:GetBucket',
  5486. ResourceKey: reqParams['prefix'],
  5487. method: 'GET',
  5488. Bucket: params.Bucket,
  5489. Region: params.Region,
  5490. headers: params.Headers,
  5491. qs: reqParams
  5492. }, function (err, data) {
  5493. if (err) return callback(err);
  5494. var ListBucketResult = data.ListBucketResult || {};
  5495. var Contents = ListBucketResult.Contents || [];
  5496. var CommonPrefixes = ListBucketResult.CommonPrefixes || [];
  5497. Contents = util.isArray(Contents) ? Contents : [Contents];
  5498. CommonPrefixes = util.isArray(CommonPrefixes) ? CommonPrefixes : [CommonPrefixes];
  5499. var result = util.clone(ListBucketResult);
  5500. util.extend(result, {
  5501. Contents: Contents,
  5502. CommonPrefixes: CommonPrefixes,
  5503. statusCode: data.statusCode,
  5504. headers: data.headers
  5505. });
  5506. callback(null, result);
  5507. });
  5508. }
  5509. /**
  5510. * 删除 Bucket
  5511. * @param {Object} params 参数对象,必须
  5512. * @param {String} params.Bucket Bucket名称,必须
  5513. * @param {String} params.Region 地域名称,必须
  5514. * @param {Function} callback 回调函数,必须
  5515. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5516. * @return {Object} data 返回的数据
  5517. * @return {String} data.Location 操作地址
  5518. */
  5519. function deleteBucket(params, callback) {
  5520. submitRequest.call(this, {
  5521. Action: 'name/cos:DeleteBucket',
  5522. Bucket: params.Bucket,
  5523. Region: params.Region,
  5524. headers: params.Headers,
  5525. method: 'DELETE'
  5526. }, function (err, data) {
  5527. if (err && err.statusCode === 204) {
  5528. return callback(null, { statusCode: err.statusCode });
  5529. } else if (err) {
  5530. return callback(err);
  5531. }
  5532. callback(null, {
  5533. statusCode: data.statusCode,
  5534. headers: data.headers
  5535. });
  5536. });
  5537. }
  5538. /**
  5539. * 设置 Bucket 的 权限列表
  5540. * @param {Object} params 参数对象,必须
  5541. * @param {String} params.Bucket Bucket名称,必须
  5542. * @param {String} params.Region 地域名称,必须
  5543. * @param {String} params.ACL 用户自定义文件权限,可以设置:private,public-read;默认值:private,非必须
  5544. * @param {String} params.GrantRead 赋予被授权者读的权限,格式x-cos-grant-read: uin=" ",uin=" ",非必须
  5545. * @param {String} params.GrantWrite 赋予被授权者写的权限,格式x-cos-grant-write: uin=" ",uin=" ",非必须
  5546. * @param {String} params.GrantFullControl 赋予被授权者读写权限,格式x-cos-grant-full-control: uin=" ",uin=" ",非必须
  5547. * @param {Function} callback 回调函数,必须
  5548. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5549. * @return {Object} data 返回的数据
  5550. */
  5551. function putBucketAcl(params, callback) {
  5552. var headers = params.Headers;
  5553. var xml = '';
  5554. if (params['AccessControlPolicy']) {
  5555. var AccessControlPolicy = util.clone(params['AccessControlPolicy'] || {});
  5556. var Grants = AccessControlPolicy.Grants || AccessControlPolicy.Grant;
  5557. Grants = util.isArray(Grants) ? Grants : [Grants];
  5558. delete AccessControlPolicy.Grant;
  5559. delete AccessControlPolicy.Grants;
  5560. AccessControlPolicy.AccessControlList = { Grant: Grants };
  5561. xml = util.json2xml({ AccessControlPolicy: AccessControlPolicy });
  5562. headers['Content-Type'] = 'application/xml';
  5563. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5564. }
  5565. // Grant Header 去重
  5566. util.each(headers, function (val, key) {
  5567. if (key.indexOf('x-cos-grant-') === 0) {
  5568. headers[key] = uniqGrant(headers[key]);
  5569. }
  5570. });
  5571. submitRequest.call(this, {
  5572. Action: 'name/cos:PutBucketACL',
  5573. method: 'PUT',
  5574. Bucket: params.Bucket,
  5575. Region: params.Region,
  5576. headers: headers,
  5577. action: 'acl',
  5578. body: xml
  5579. }, function (err, data) {
  5580. if (err) return callback(err);
  5581. callback(null, {
  5582. statusCode: data.statusCode,
  5583. headers: data.headers
  5584. });
  5585. });
  5586. }
  5587. /**
  5588. * 获取 Bucket 的 权限列表
  5589. * @param {Object} params 参数对象,必须
  5590. * @param {String} params.Bucket Bucket名称,必须
  5591. * @param {String} params.Region 地域名称,必须
  5592. * @param {Function} callback 回调函数,必须
  5593. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5594. * @return {Object} data 返回的数据
  5595. * @return {Object} data.AccessControlPolicy 访问权限信息
  5596. */
  5597. function getBucketAcl(params, callback) {
  5598. submitRequest.call(this, {
  5599. Action: 'name/cos:GetBucketACL',
  5600. method: 'GET',
  5601. Bucket: params.Bucket,
  5602. Region: params.Region,
  5603. headers: params.Headers,
  5604. action: 'acl'
  5605. }, function (err, data) {
  5606. if (err) return callback(err);
  5607. var AccessControlPolicy = data.AccessControlPolicy || {};
  5608. var Owner = AccessControlPolicy.Owner || {};
  5609. var Grant = AccessControlPolicy.AccessControlList.Grant || [];
  5610. Grant = util.isArray(Grant) ? Grant : [Grant];
  5611. var result = decodeAcl(AccessControlPolicy);
  5612. if (data.headers && data.headers['x-cos-acl']) {
  5613. result.ACL = data.headers['x-cos-acl'];
  5614. }
  5615. result = util.extend(result, {
  5616. Owner: Owner,
  5617. Grants: Grant,
  5618. statusCode: data.statusCode,
  5619. headers: data.headers
  5620. });
  5621. callback(null, result);
  5622. });
  5623. }
  5624. /**
  5625. * 设置 Bucket 的 跨域设置
  5626. * @param {Object} params 参数对象,必须
  5627. * @param {String} params.Bucket Bucket名称,必须
  5628. * @param {String} params.Region 地域名称,必须
  5629. * @param {Object} params.CORSConfiguration 相关的跨域设置,必须
  5630. * @param {Array} params.CORSConfiguration.CORSRules 对应的跨域规则
  5631. * @param {Function} callback 回调函数,必须
  5632. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5633. * @return {Object} data 返回的数据
  5634. */
  5635. function putBucketCors(params, callback) {
  5636. var CORSConfiguration = params['CORSConfiguration'] || {};
  5637. var CORSRules = CORSConfiguration['CORSRules'] || params['CORSRules'] || [];
  5638. CORSRules = util.clone(util.isArray(CORSRules) ? CORSRules : [CORSRules]);
  5639. util.each(CORSRules, function (rule) {
  5640. util.each(['AllowedOrigin', 'AllowedHeader', 'AllowedMethod', 'ExposeHeader'], function (key) {
  5641. var sKey = key + 's';
  5642. var val = rule[sKey] || rule[key] || [];
  5643. delete rule[sKey];
  5644. rule[key] = util.isArray(val) ? val : [val];
  5645. });
  5646. });
  5647. var Conf = { CORSRule: CORSRules };
  5648. if (params.ResponseVary) Conf.ResponseVary = params.ResponseVary;
  5649. var xml = util.json2xml({ CORSConfiguration: Conf });
  5650. var headers = params.Headers;
  5651. headers['Content-Type'] = 'application/xml';
  5652. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5653. submitRequest.call(this, {
  5654. Action: 'name/cos:PutBucketCORS',
  5655. method: 'PUT',
  5656. Bucket: params.Bucket,
  5657. Region: params.Region,
  5658. body: xml,
  5659. action: 'cors',
  5660. headers: headers
  5661. }, function (err, data) {
  5662. if (err) return callback(err);
  5663. callback(null, {
  5664. statusCode: data.statusCode,
  5665. headers: data.headers
  5666. });
  5667. });
  5668. }
  5669. /**
  5670. * 获取 Bucket 的 跨域设置
  5671. * @param {Object} params 参数对象,必须
  5672. * @param {String} params.Bucket Bucket名称,必须
  5673. * @param {String} params.Region 地域名称,必须
  5674. * @param {Function} callback 回调函数,必须
  5675. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5676. * @return {Object} data 返回的数据
  5677. * @return {Object} data.CORSRules Bucket的跨域设置
  5678. */
  5679. function getBucketCors(params, callback) {
  5680. submitRequest.call(this, {
  5681. Action: 'name/cos:GetBucketCORS',
  5682. method: 'GET',
  5683. Bucket: params.Bucket,
  5684. Region: params.Region,
  5685. headers: params.Headers,
  5686. action: 'cors'
  5687. }, function (err, data) {
  5688. if (err) {
  5689. if (err.statusCode === 404 && err.error && err.error.Code === 'NoSuchCORSConfiguration') {
  5690. var result = {
  5691. CORSRules: [],
  5692. statusCode: err.statusCode
  5693. };
  5694. err.headers && (result.headers = err.headers);
  5695. callback(null, result);
  5696. } else {
  5697. callback(err);
  5698. }
  5699. return;
  5700. }
  5701. var CORSConfiguration = data.CORSConfiguration || {};
  5702. var CORSRules = CORSConfiguration.CORSRules || CORSConfiguration.CORSRule || [];
  5703. CORSRules = util.clone(util.isArray(CORSRules) ? CORSRules : [CORSRules]);
  5704. var ResponseVary = CORSConfiguration.ResponseVary;
  5705. util.each(CORSRules, function (rule) {
  5706. util.each(['AllowedOrigin', 'AllowedHeader', 'AllowedMethod', 'ExposeHeader'], function (key) {
  5707. var sKey = key + 's';
  5708. var val = rule[sKey] || rule[key] || [];
  5709. delete rule[key];
  5710. rule[sKey] = util.isArray(val) ? val : [val];
  5711. });
  5712. });
  5713. callback(null, {
  5714. CORSRules: CORSRules,
  5715. ResponseVary: ResponseVary,
  5716. statusCode: data.statusCode,
  5717. headers: data.headers
  5718. });
  5719. });
  5720. }
  5721. /**
  5722. * 删除 Bucket 的 跨域设置
  5723. * @param {Object} params 参数对象,必须
  5724. * @param {String} params.Bucket Bucket名称,必须
  5725. * @param {String} params.Region 地域名称,必须
  5726. * @param {Function} callback 回调函数,必须
  5727. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5728. * @return {Object} data 返回的数据
  5729. */
  5730. function deleteBucketCors(params, callback) {
  5731. submitRequest.call(this, {
  5732. Action: 'name/cos:DeleteBucketCORS',
  5733. method: 'DELETE',
  5734. Bucket: params.Bucket,
  5735. Region: params.Region,
  5736. headers: params.Headers,
  5737. action: 'cors'
  5738. }, function (err, data) {
  5739. if (err && err.statusCode === 204) {
  5740. return callback(null, { statusCode: err.statusCode });
  5741. } else if (err) {
  5742. return callback(err);
  5743. }
  5744. callback(null, {
  5745. statusCode: data.statusCode || err.statusCode,
  5746. headers: data.headers
  5747. });
  5748. });
  5749. }
  5750. /**
  5751. * 获取 Bucket 的 地域信息
  5752. * @param {Object} params 参数对象,必须
  5753. * @param {String} params.Bucket Bucket名称,必须
  5754. * @param {String} params.Region 地域名称,必须
  5755. * @param {Function} callback 回调函数,必须
  5756. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5757. * @return {Object} data 返回数据,包含地域信息 LocationConstraint
  5758. */
  5759. function getBucketLocation(params, callback) {
  5760. submitRequest.call(this, {
  5761. Action: 'name/cos:GetBucketLocation',
  5762. method: 'GET',
  5763. Bucket: params.Bucket,
  5764. Region: params.Region,
  5765. headers: params.Headers,
  5766. action: 'location'
  5767. }, callback);
  5768. }
  5769. function putBucketPolicy(params, callback) {
  5770. var Policy = params['Policy'];
  5771. try {
  5772. if (typeof Policy === 'string') Policy = JSON.parse(Policy);
  5773. } catch (e) {}
  5774. if (!Policy || typeof Policy === 'string') return callback(util.error(new Error('Policy format error')));
  5775. var PolicyStr = JSON.stringify(Policy);
  5776. if (!Policy.version) Policy.version = '2.0';
  5777. var headers = params.Headers;
  5778. headers['Content-Type'] = 'application/json';
  5779. headers['Content-MD5'] = util.binaryBase64(util.md5(PolicyStr));
  5780. submitRequest.call(this, {
  5781. Action: 'name/cos:PutBucketPolicy',
  5782. method: 'PUT',
  5783. Bucket: params.Bucket,
  5784. Region: params.Region,
  5785. action: 'policy',
  5786. body: PolicyStr,
  5787. headers: headers
  5788. }, function (err, data) {
  5789. if (err && err.statusCode === 204) {
  5790. return callback(null, { statusCode: err.statusCode });
  5791. } else if (err) {
  5792. return callback(err);
  5793. }
  5794. callback(null, {
  5795. statusCode: data.statusCode,
  5796. headers: data.headers
  5797. });
  5798. });
  5799. }
  5800. /**
  5801. * 获取 Bucket 的读取权限策略
  5802. * @param {Object} params 参数对象,必须
  5803. * @param {String} params.Bucket Bucket名称,必须
  5804. * @param {String} params.Region 地域名称,必须
  5805. * @param {Function} callback 回调函数,必须
  5806. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5807. * @return {Object} data 返回数据
  5808. */
  5809. function getBucketPolicy(params, callback) {
  5810. submitRequest.call(this, {
  5811. Action: 'name/cos:GetBucketPolicy',
  5812. method: 'GET',
  5813. Bucket: params.Bucket,
  5814. Region: params.Region,
  5815. headers: params.Headers,
  5816. action: 'policy',
  5817. rawBody: true
  5818. }, function (err, data) {
  5819. if (err) {
  5820. if (err.statusCode && err.statusCode === 403) {
  5821. return callback(util.error(err, { ErrorStatus: 'Access Denied' }));
  5822. }
  5823. if (err.statusCode && err.statusCode === 405) {
  5824. return callback(util.error(err, { ErrorStatus: 'Method Not Allowed' }));
  5825. }
  5826. if (err.statusCode && err.statusCode === 404) {
  5827. return callback(util.error(err, { ErrorStatus: 'Policy Not Found' }));
  5828. }
  5829. return callback(err);
  5830. }
  5831. var Policy = {};
  5832. try {
  5833. Policy = JSON.parse(data.body);
  5834. } catch (e) {}
  5835. callback(null, {
  5836. Policy: Policy,
  5837. statusCode: data.statusCode,
  5838. headers: data.headers
  5839. });
  5840. });
  5841. }
  5842. /**
  5843. * 删除 Bucket 的 跨域设置
  5844. * @param {Object} params 参数对象,必须
  5845. * @param {String} params.Bucket Bucket名称,必须
  5846. * @param {String} params.Region 地域名称,必须
  5847. * @param {Function} callback 回调函数,必须
  5848. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5849. * @return {Object} data 返回的数据
  5850. */
  5851. function deleteBucketPolicy(params, callback) {
  5852. submitRequest.call(this, {
  5853. Action: 'name/cos:DeleteBucketPolicy',
  5854. method: 'DELETE',
  5855. Bucket: params.Bucket,
  5856. Region: params.Region,
  5857. headers: params.Headers,
  5858. action: 'policy'
  5859. }, function (err, data) {
  5860. if (err && err.statusCode === 204) {
  5861. return callback(null, { statusCode: err.statusCode });
  5862. } else if (err) {
  5863. return callback(err);
  5864. }
  5865. callback(null, {
  5866. statusCode: data.statusCode || err.statusCode,
  5867. headers: data.headers
  5868. });
  5869. });
  5870. }
  5871. /**
  5872. * 设置 Bucket 的标签
  5873. * @param {Object} params 参数对象,必须
  5874. * @param {String} params.Bucket Bucket名称,必须
  5875. * @param {String} params.Region 地域名称,必须
  5876. * @param {Array} params.TagSet 标签设置,必须
  5877. * @param {Function} callback 回调函数,必须
  5878. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5879. * @return {Object} data 返回数据
  5880. */
  5881. function putBucketTagging(params, callback) {
  5882. var Tagging = params['Tagging'] || {};
  5883. var Tags = Tagging.TagSet || Tagging.Tags || params['Tags'] || [];
  5884. Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
  5885. var xml = util.json2xml({ Tagging: { TagSet: { Tag: Tags } } });
  5886. var headers = params.Headers;
  5887. headers['Content-Type'] = 'application/xml';
  5888. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5889. submitRequest.call(this, {
  5890. Action: 'name/cos:PutBucketTagging',
  5891. method: 'PUT',
  5892. Bucket: params.Bucket,
  5893. Region: params.Region,
  5894. body: xml,
  5895. action: 'tagging',
  5896. headers: headers
  5897. }, function (err, data) {
  5898. if (err && err.statusCode === 204) {
  5899. return callback(null, { statusCode: err.statusCode });
  5900. } else if (err) {
  5901. return callback(err);
  5902. }
  5903. callback(null, {
  5904. statusCode: data.statusCode,
  5905. headers: data.headers
  5906. });
  5907. });
  5908. }
  5909. /**
  5910. * 获取 Bucket 的标签设置
  5911. * @param {Object} params 参数对象,必须
  5912. * @param {String} params.Bucket Bucket名称,必须
  5913. * @param {String} params.Region 地域名称,必须
  5914. * @param {Function} callback 回调函数,必须
  5915. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5916. * @return {Object} data 返回数据
  5917. */
  5918. function getBucketTagging(params, callback) {
  5919. submitRequest.call(this, {
  5920. Action: 'name/cos:GetBucketTagging',
  5921. method: 'GET',
  5922. Bucket: params.Bucket,
  5923. Region: params.Region,
  5924. headers: params.Headers,
  5925. action: 'tagging'
  5926. }, function (err, data) {
  5927. if (err) {
  5928. if (err.statusCode === 404 && err.error && (err.error === "Not Found" || err.error.Code === 'NoSuchTagSet')) {
  5929. var result = {
  5930. Tags: [],
  5931. statusCode: err.statusCode
  5932. };
  5933. err.headers && (result.headers = err.headers);
  5934. callback(null, result);
  5935. } else {
  5936. callback(err);
  5937. }
  5938. return;
  5939. }
  5940. var Tags = [];
  5941. try {
  5942. Tags = data.Tagging.TagSet.Tag || [];
  5943. } catch (e) {}
  5944. Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
  5945. callback(null, {
  5946. Tags: Tags,
  5947. statusCode: data.statusCode,
  5948. headers: data.headers
  5949. });
  5950. });
  5951. }
  5952. /**
  5953. * 删除 Bucket 的 标签设置
  5954. * @param {Object} params 参数对象,必须
  5955. * @param {String} params.Bucket Bucket名称,必须
  5956. * @param {String} params.Region 地域名称,必须
  5957. * @param {Function} callback 回调函数,必须
  5958. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  5959. * @return {Object} data 返回的数据
  5960. */
  5961. function deleteBucketTagging(params, callback) {
  5962. submitRequest.call(this, {
  5963. Action: 'name/cos:DeleteBucketTagging',
  5964. method: 'DELETE',
  5965. Bucket: params.Bucket,
  5966. Region: params.Region,
  5967. headers: params.Headers,
  5968. action: 'tagging'
  5969. }, function (err, data) {
  5970. if (err && err.statusCode === 204) {
  5971. return callback(null, { statusCode: err.statusCode });
  5972. } else if (err) {
  5973. return callback(err);
  5974. }
  5975. callback(null, {
  5976. statusCode: data.statusCode,
  5977. headers: data.headers
  5978. });
  5979. });
  5980. }
  5981. function putBucketLifecycle(params, callback) {
  5982. var LifecycleConfiguration = params['LifecycleConfiguration'] || {};
  5983. var Rules = LifecycleConfiguration.Rules || params.Rules || [];
  5984. Rules = util.clone(Rules);
  5985. var xml = util.json2xml({ LifecycleConfiguration: { Rule: Rules } });
  5986. var headers = params.Headers;
  5987. headers['Content-Type'] = 'application/xml';
  5988. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  5989. submitRequest.call(this, {
  5990. Action: 'name/cos:PutBucketLifecycle',
  5991. method: 'PUT',
  5992. Bucket: params.Bucket,
  5993. Region: params.Region,
  5994. body: xml,
  5995. action: 'lifecycle',
  5996. headers: headers
  5997. }, function (err, data) {
  5998. if (err && err.statusCode === 204) {
  5999. return callback(null, { statusCode: err.statusCode });
  6000. } else if (err) {
  6001. return callback(err);
  6002. }
  6003. callback(null, {
  6004. statusCode: data.statusCode,
  6005. headers: data.headers
  6006. });
  6007. });
  6008. }
  6009. function getBucketLifecycle(params, callback) {
  6010. submitRequest.call(this, {
  6011. Action: 'name/cos:GetBucketLifecycle',
  6012. method: 'GET',
  6013. Bucket: params.Bucket,
  6014. Region: params.Region,
  6015. headers: params.Headers,
  6016. action: 'lifecycle'
  6017. }, function (err, data) {
  6018. if (err) {
  6019. if (err.statusCode === 404 && err.error && err.error.Code === 'NoSuchLifecycleConfiguration') {
  6020. var result = {
  6021. Rules: [],
  6022. statusCode: err.statusCode
  6023. };
  6024. err.headers && (result.headers = err.headers);
  6025. callback(null, result);
  6026. } else {
  6027. callback(err);
  6028. }
  6029. return;
  6030. }
  6031. var Rules = [];
  6032. try {
  6033. Rules = data.LifecycleConfiguration.Rule || [];
  6034. } catch (e) {}
  6035. Rules = util.clone(util.isArray(Rules) ? Rules : [Rules]);
  6036. callback(null, {
  6037. Rules: Rules,
  6038. statusCode: data.statusCode,
  6039. headers: data.headers
  6040. });
  6041. });
  6042. }
  6043. function deleteBucketLifecycle(params, callback) {
  6044. submitRequest.call(this, {
  6045. Action: 'name/cos:DeleteBucketLifecycle',
  6046. method: 'DELETE',
  6047. Bucket: params.Bucket,
  6048. Region: params.Region,
  6049. headers: params.Headers,
  6050. action: 'lifecycle'
  6051. }, function (err, data) {
  6052. if (err && err.statusCode === 204) {
  6053. return callback(null, { statusCode: err.statusCode });
  6054. } else if (err) {
  6055. return callback(err);
  6056. }
  6057. callback(null, {
  6058. statusCode: data.statusCode,
  6059. headers: data.headers
  6060. });
  6061. });
  6062. }
  6063. function putBucketVersioning(params, callback) {
  6064. if (!params['VersioningConfiguration']) {
  6065. callback(util.error(new Error('missing param VersioningConfiguration')));
  6066. return;
  6067. }
  6068. var VersioningConfiguration = params['VersioningConfiguration'] || {};
  6069. var xml = util.json2xml({ VersioningConfiguration: VersioningConfiguration });
  6070. var headers = params.Headers;
  6071. headers['Content-Type'] = 'application/xml';
  6072. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6073. submitRequest.call(this, {
  6074. Action: 'name/cos:PutBucketVersioning',
  6075. method: 'PUT',
  6076. Bucket: params.Bucket,
  6077. Region: params.Region,
  6078. body: xml,
  6079. action: 'versioning',
  6080. headers: headers
  6081. }, function (err, data) {
  6082. if (err && err.statusCode === 204) {
  6083. return callback(null, { statusCode: err.statusCode });
  6084. } else if (err) {
  6085. return callback(err);
  6086. }
  6087. callback(null, {
  6088. statusCode: data.statusCode,
  6089. headers: data.headers
  6090. });
  6091. });
  6092. }
  6093. function getBucketVersioning(params, callback) {
  6094. submitRequest.call(this, {
  6095. Action: 'name/cos:GetBucketVersioning',
  6096. method: 'GET',
  6097. Bucket: params.Bucket,
  6098. Region: params.Region,
  6099. headers: params.Headers,
  6100. action: 'versioning'
  6101. }, function (err, data) {
  6102. if (!err) {
  6103. !data.VersioningConfiguration && (data.VersioningConfiguration = {});
  6104. }
  6105. callback(err, data);
  6106. });
  6107. }
  6108. function putBucketReplication(params, callback) {
  6109. var ReplicationConfiguration = util.clone(params.ReplicationConfiguration);
  6110. var xml = util.json2xml({ ReplicationConfiguration: ReplicationConfiguration });
  6111. xml = xml.replace(/<(\/?)Rules>/ig, '<$1Rule>');
  6112. xml = xml.replace(/<(\/?)Tags>/ig, '<$1Tag>');
  6113. var headers = params.Headers;
  6114. headers['Content-Type'] = 'application/xml';
  6115. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6116. submitRequest.call(this, {
  6117. Action: 'name/cos:PutBucketReplication',
  6118. method: 'PUT',
  6119. Bucket: params.Bucket,
  6120. Region: params.Region,
  6121. body: xml,
  6122. action: 'replication',
  6123. headers: headers
  6124. }, function (err, data) {
  6125. if (err && err.statusCode === 204) {
  6126. return callback(null, { statusCode: err.statusCode });
  6127. } else if (err) {
  6128. return callback(err);
  6129. }
  6130. callback(null, {
  6131. statusCode: data.statusCode,
  6132. headers: data.headers
  6133. });
  6134. });
  6135. }
  6136. function getBucketReplication(params, callback) {
  6137. submitRequest.call(this, {
  6138. Action: 'name/cos:GetBucketReplication',
  6139. method: 'GET',
  6140. Bucket: params.Bucket,
  6141. Region: params.Region,
  6142. headers: params.Headers,
  6143. action: 'replication'
  6144. }, function (err, data) {
  6145. if (err) {
  6146. if (err.statusCode === 404 && err.error && (err.error === 'Not Found' || err.error.Code === 'ReplicationConfigurationnotFoundError')) {
  6147. var result = {
  6148. ReplicationConfiguration: { Rules: [] },
  6149. statusCode: err.statusCode
  6150. };
  6151. err.headers && (result.headers = err.headers);
  6152. callback(null, result);
  6153. } else {
  6154. callback(err);
  6155. }
  6156. return;
  6157. }
  6158. !data.ReplicationConfiguration && (data.ReplicationConfiguration = {});
  6159. if (data.ReplicationConfiguration.Rule) {
  6160. data.ReplicationConfiguration.Rules = util.makeArray(data.ReplicationConfiguration.Rule);
  6161. delete data.ReplicationConfiguration.Rule;
  6162. }
  6163. callback(err, data);
  6164. });
  6165. }
  6166. function deleteBucketReplication(params, callback) {
  6167. submitRequest.call(this, {
  6168. Action: 'name/cos:DeleteBucketReplication',
  6169. method: 'DELETE',
  6170. Bucket: params.Bucket,
  6171. Region: params.Region,
  6172. headers: params.Headers,
  6173. action: 'replication'
  6174. }, function (err, data) {
  6175. if (err && err.statusCode === 204) {
  6176. return callback(null, { statusCode: err.statusCode });
  6177. } else if (err) {
  6178. return callback(err);
  6179. }
  6180. callback(null, {
  6181. statusCode: data.statusCode,
  6182. headers: data.headers
  6183. });
  6184. });
  6185. }
  6186. /**
  6187. * 设置 Bucket 静态网站配置信息
  6188. * @param {Object} params 参数对象,必须
  6189. * @param {String} params.Bucket Bucket名称,必须
  6190. * @param {String} params.Region 地域名称,必须
  6191. * @param {Object} params.WebsiteConfiguration 地域名称,必须
  6192. * @param {Object} WebsiteConfiguration.IndexDocument 索引文档,必须
  6193. * @param {Object} WebsiteConfiguration.ErrorDocument 错误文档,非必须
  6194. * @param {Object} WebsiteConfiguration.RedirectAllRequestsTo 重定向所有请求,非必须
  6195. * @param {Array} params.RoutingRules 重定向规则,非必须
  6196. * @param {Function} callback 回调函数,必须
  6197. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6198. * @return {Object} data 返回数据
  6199. */
  6200. function putBucketWebsite(params, callback) {
  6201. if (!params['WebsiteConfiguration']) {
  6202. callback(util.error(new Error('missing param WebsiteConfiguration')));
  6203. return;
  6204. }
  6205. var WebsiteConfiguration = util.clone(params['WebsiteConfiguration'] || {});
  6206. var RoutingRules = WebsiteConfiguration['RoutingRules'] || WebsiteConfiguration['RoutingRule'] || [];
  6207. RoutingRules = util.isArray(RoutingRules) ? RoutingRules : [RoutingRules];
  6208. delete WebsiteConfiguration.RoutingRule;
  6209. delete WebsiteConfiguration.RoutingRules;
  6210. if (RoutingRules.length) WebsiteConfiguration.RoutingRules = { RoutingRule: RoutingRules };
  6211. var xml = util.json2xml({ WebsiteConfiguration: WebsiteConfiguration });
  6212. var headers = params.Headers;
  6213. headers['Content-Type'] = 'application/xml';
  6214. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6215. submitRequest.call(this, {
  6216. Action: 'name/cos:PutBucketWebsite',
  6217. method: 'PUT',
  6218. Bucket: params.Bucket,
  6219. Region: params.Region,
  6220. body: xml,
  6221. action: 'website',
  6222. headers: headers
  6223. }, function (err, data) {
  6224. if (err && err.statusCode === 204) {
  6225. return callback(null, { statusCode: err.statusCode });
  6226. } else if (err) {
  6227. return callback(err);
  6228. }
  6229. callback(null, {
  6230. statusCode: data.statusCode,
  6231. headers: data.headers
  6232. });
  6233. });
  6234. }
  6235. /**
  6236. * 获取 Bucket 的静态网站配置信息
  6237. * @param {Object} params 参数对象,必须
  6238. * @param {String} params.Bucket Bucket名称,必须
  6239. * @param {String} params.Region 地域名称,必须
  6240. * @param {Function} callback 回调函数,必须
  6241. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6242. * @return {Object} data 返回数据
  6243. */
  6244. function getBucketWebsite(params, callback) {
  6245. submitRequest.call(this, {
  6246. Action: 'name/cos:GetBucketWebsite',
  6247. method: 'GET',
  6248. Bucket: params.Bucket,
  6249. Region: params.Region,
  6250. Key: params.Key,
  6251. headers: params.Headers,
  6252. action: 'website'
  6253. }, function (err, data) {
  6254. if (err) {
  6255. if (err.statusCode === 404 && err.error.Code === 'NoSuchWebsiteConfiguration') {
  6256. var result = {
  6257. WebsiteConfiguration: {},
  6258. statusCode: err.statusCode
  6259. };
  6260. err.headers && (result.headers = err.headers);
  6261. callback(null, result);
  6262. } else {
  6263. callback(err);
  6264. }
  6265. return;
  6266. }
  6267. var WebsiteConfiguration = data.WebsiteConfiguration || {};
  6268. if (WebsiteConfiguration['RoutingRules']) {
  6269. var RoutingRules = util.clone(WebsiteConfiguration['RoutingRules'].RoutingRule || []);
  6270. RoutingRules = util.makeArray(RoutingRules);
  6271. WebsiteConfiguration.RoutingRules = RoutingRules;
  6272. }
  6273. callback(null, {
  6274. WebsiteConfiguration: WebsiteConfiguration,
  6275. statusCode: data.statusCode,
  6276. headers: data.headers
  6277. });
  6278. });
  6279. }
  6280. /**
  6281. * 删除 Bucket 的静态网站配置
  6282. * @param {Object} params 参数对象,必须
  6283. * @param {String} params.Bucket Bucket名称,必须
  6284. * @param {String} params.Region 地域名称,必须
  6285. * @param {Function} callback 回调函数,必须
  6286. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6287. * @return {Object} data 返回数据
  6288. */
  6289. function deleteBucketWebsite(params, callback) {
  6290. submitRequest.call(this, {
  6291. Action: 'name/cos:DeleteBucketWebsite',
  6292. method: 'DELETE',
  6293. Bucket: params.Bucket,
  6294. Region: params.Region,
  6295. headers: params.Headers,
  6296. action: 'website'
  6297. }, function (err, data) {
  6298. if (err && err.statusCode === 204) {
  6299. return callback(null, { statusCode: err.statusCode });
  6300. } else if (err) {
  6301. return callback(err);
  6302. }
  6303. callback(null, {
  6304. statusCode: data.statusCode,
  6305. headers: data.headers
  6306. });
  6307. });
  6308. }
  6309. /**
  6310. * 设置 Bucket 的防盗链白名单或者黑名单
  6311. * @param {Object} params 参数对象,必须
  6312. * @param {String} params.Bucket Bucket名称,必须
  6313. * @param {String} params.Region 地域名称,必须
  6314. * @param {Object} params.RefererConfiguration 地域名称,必须
  6315. * @param {String} RefererConfiguration.Status 是否开启防盗链,枚举值:Enabled、Disabled
  6316. * @param {String} RefererConfiguration.RefererType 防盗链类型,枚举值:Black-List、White-List,必须
  6317. * @param {Array} RefererConfiguration.DomianList.Domain 生效域名,必须
  6318. * @param {String} RefererConfiguration.EmptyReferConfiguration ,非必须
  6319. * @param {Function} callback 回调函数,必须
  6320. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6321. * @return {Object} data 返回数据
  6322. */
  6323. function putBucketReferer(params, callback) {
  6324. if (!params['RefererConfiguration']) {
  6325. callback(util.error(new Error('missing param RefererConfiguration')));
  6326. return;
  6327. }
  6328. var RefererConfiguration = util.clone(params['RefererConfiguration'] || {});
  6329. var DomainList = RefererConfiguration['DomainList'] || {};
  6330. var Domains = DomainList['Domains'] || DomainList['Domain'] || [];
  6331. Domains = util.isArray(Domains) ? Domains : [Domains];
  6332. if (Domains.length) RefererConfiguration.DomainList = { Domain: Domains };
  6333. var xml = util.json2xml({ RefererConfiguration: RefererConfiguration });
  6334. var headers = params.Headers;
  6335. headers['Content-Type'] = 'application/xml';
  6336. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6337. submitRequest.call(this, {
  6338. Action: 'name/cos:PutBucketReferer',
  6339. method: 'PUT',
  6340. Bucket: params.Bucket,
  6341. Region: params.Region,
  6342. body: xml,
  6343. action: 'referer',
  6344. headers: headers
  6345. }, function (err, data) {
  6346. if (err && err.statusCode === 204) {
  6347. return callback(null, { statusCode: err.statusCode });
  6348. } else if (err) {
  6349. return callback(err);
  6350. }
  6351. callback(null, {
  6352. statusCode: data.statusCode,
  6353. headers: data.headers
  6354. });
  6355. });
  6356. }
  6357. /**
  6358. * 获取 Bucket 的防盗链白名单或者黑名单
  6359. * @param {Object} params 参数对象,必须
  6360. * @param {String} params.Bucket Bucket名称,必须
  6361. * @param {String} params.Region 地域名称,必须
  6362. * @param {Function} callback 回调函数,必须
  6363. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6364. * @return {Object} data 返回数据
  6365. */
  6366. function getBucketReferer(params, callback) {
  6367. submitRequest.call(this, {
  6368. Action: 'name/cos:GetBucketReferer',
  6369. method: 'GET',
  6370. Bucket: params.Bucket,
  6371. Region: params.Region,
  6372. Key: params.Key,
  6373. headers: params.Headers,
  6374. action: 'referer'
  6375. }, function (err, data) {
  6376. if (err) {
  6377. if (err.statusCode === 404 && err.error.Code === 'NoSuchRefererConfiguration') {
  6378. var result = {
  6379. WebsiteConfiguration: {},
  6380. statusCode: err.statusCode
  6381. };
  6382. err.headers && (result.headers = err.headers);
  6383. callback(null, result);
  6384. } else {
  6385. callback(err);
  6386. }
  6387. return;
  6388. }
  6389. var RefererConfiguration = data.RefererConfiguration || {};
  6390. if (RefererConfiguration['DomainList']) {
  6391. var Domains = util.makeArray(RefererConfiguration['DomainList'].Domain || []);
  6392. RefererConfiguration.DomainList = { Domains: Domains };
  6393. }
  6394. callback(null, {
  6395. RefererConfiguration: RefererConfiguration,
  6396. statusCode: data.statusCode,
  6397. headers: data.headers
  6398. });
  6399. });
  6400. }
  6401. /**
  6402. * 设置 Bucket 自定义域名
  6403. * @param {Object} params 参数对象,必须
  6404. * @param {String} params.Bucket Bucket名称,必须
  6405. * @param {String} params.Region 地域名称,必须
  6406. * @param {Function} callback 回调函数,必须
  6407. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6408. * @return {Object} data 返回数据
  6409. */
  6410. function putBucketDomain(params, callback) {
  6411. var DomainConfiguration = params['DomainConfiguration'] || {};
  6412. var DomainRule = DomainConfiguration.DomainRule || params.DomainRule || [];
  6413. DomainRule = util.clone(DomainRule);
  6414. var xml = util.json2xml({ DomainConfiguration: { DomainRule: DomainRule } });
  6415. var headers = params.Headers;
  6416. headers['Content-Type'] = 'application/xml';
  6417. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6418. submitRequest.call(this, {
  6419. Action: 'name/cos:PutBucketDomain',
  6420. method: 'PUT',
  6421. Bucket: params.Bucket,
  6422. Region: params.Region,
  6423. body: xml,
  6424. action: 'domain',
  6425. headers: headers
  6426. }, function (err, data) {
  6427. if (err && err.statusCode === 204) {
  6428. return callback(null, { statusCode: err.statusCode });
  6429. } else if (err) {
  6430. return callback(err);
  6431. }
  6432. callback(null, {
  6433. statusCode: data.statusCode,
  6434. headers: data.headers
  6435. });
  6436. });
  6437. }
  6438. /**
  6439. * 获取 Bucket 的自定义域名
  6440. * @param {Object} params 参数对象,必须
  6441. * @param {String} params.Bucket Bucket名称,必须
  6442. * @param {String} params.Region 地域名称,必须
  6443. * @param {Function} callback 回调函数,必须
  6444. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6445. * @return {Object} data 返回数据
  6446. */
  6447. function getBucketDomain(params, callback) {
  6448. submitRequest.call(this, {
  6449. Action: 'name/cos:GetBucketDomain',
  6450. method: 'GET',
  6451. Bucket: params.Bucket,
  6452. Region: params.Region,
  6453. headers: params.Headers,
  6454. action: 'domain'
  6455. }, function (err, data) {
  6456. if (err) return callback(err);
  6457. var DomainRule = [];
  6458. try {
  6459. DomainRule = data.DomainConfiguration.DomainRule || [];
  6460. } catch (e) {}
  6461. DomainRule = util.clone(util.isArray(DomainRule) ? DomainRule : [DomainRule]);
  6462. callback(null, {
  6463. DomainRule: DomainRule,
  6464. statusCode: data.statusCode,
  6465. headers: data.headers
  6466. });
  6467. });
  6468. }
  6469. /**
  6470. * 删除 Bucket 自定义域名
  6471. * @param {Object} params 参数对象,必须
  6472. * @param {String} params.Bucket Bucket名称,必须
  6473. * @param {String} params.Region 地域名称,必须
  6474. * @param {Function} callback 回调函数,必须
  6475. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6476. * @return {Object} data 返回数据
  6477. */
  6478. function deleteBucketDomain(params, callback) {
  6479. submitRequest.call(this, {
  6480. Action: 'name/cos:DeleteBucketDomain',
  6481. method: 'DELETE',
  6482. Bucket: params.Bucket,
  6483. Region: params.Region,
  6484. headers: params.Headers,
  6485. action: 'domain'
  6486. }, function (err, data) {
  6487. if (err && err.statusCode === 204) {
  6488. return callback(null, { statusCode: err.statusCode });
  6489. } else if (err) {
  6490. return callback(err);
  6491. }
  6492. callback(null, {
  6493. statusCode: data.statusCode,
  6494. headers: data.headers
  6495. });
  6496. });
  6497. }
  6498. /**
  6499. * 设置 Bucket 的回源
  6500. * @param {Object} params 参数对象,必须
  6501. * @param {String} params.Bucket Bucket名称,必须
  6502. * @param {String} params.Region 地域名称,必须
  6503. * @param {Function} callback 回调函数,必须
  6504. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6505. * @return {Object} data 返回数据
  6506. */
  6507. function putBucketOrigin(params, callback) {
  6508. var OriginConfiguration = params['OriginConfiguration'] || {};
  6509. var OriginRule = OriginConfiguration.OriginRule || params.OriginRule || [];
  6510. OriginRule = util.clone(OriginRule);
  6511. var xml = util.json2xml({ OriginConfiguration: { OriginRule: OriginRule } });
  6512. var headers = params.Headers;
  6513. headers['Content-Type'] = 'application/xml';
  6514. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6515. submitRequest.call(this, {
  6516. Action: 'name/cos:PutBucketOrigin',
  6517. method: 'PUT',
  6518. Bucket: params.Bucket,
  6519. Region: params.Region,
  6520. body: xml,
  6521. action: 'origin',
  6522. headers: headers
  6523. }, function (err, data) {
  6524. if (err && err.statusCode === 204) {
  6525. return callback(null, { statusCode: err.statusCode });
  6526. } else if (err) {
  6527. return callback(err);
  6528. }
  6529. callback(null, {
  6530. statusCode: data.statusCode,
  6531. headers: data.headers
  6532. });
  6533. });
  6534. }
  6535. /**
  6536. * 获取 Bucket 的回源
  6537. * @param {Object} params 参数对象,必须
  6538. * @param {String} params.Bucket Bucket名称,必须
  6539. * @param {String} params.Region 地域名称,必须
  6540. * @param {Function} callback 回调函数,必须
  6541. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6542. * @return {Object} data 返回数据
  6543. */
  6544. function getBucketOrigin(params, callback) {
  6545. submitRequest.call(this, {
  6546. Action: 'name/cos:GetBucketOrigin',
  6547. method: 'GET',
  6548. Bucket: params.Bucket,
  6549. Region: params.Region,
  6550. headers: params.Headers,
  6551. action: 'origin'
  6552. }, function (err, data) {
  6553. if (err) return callback(err);
  6554. var OriginRule = [];
  6555. try {
  6556. OriginRule = data.OriginConfiguration.OriginRule || [];
  6557. } catch (e) {}
  6558. OriginRule = util.clone(util.isArray(OriginRule) ? OriginRule : [OriginRule]);
  6559. callback(null, {
  6560. OriginRule: OriginRule,
  6561. statusCode: data.statusCode,
  6562. headers: data.headers
  6563. });
  6564. });
  6565. }
  6566. /**
  6567. * 删除 Bucket 的回源
  6568. * @param {Object} params 参数对象,必须
  6569. * @param {String} params.Bucket Bucket名称,必须
  6570. * @param {String} params.Region 地域名称,必须
  6571. * @param {Function} callback 回调函数,必须
  6572. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6573. * @return {Object} data 返回数据
  6574. */
  6575. function deleteBucketOrigin(params, callback) {
  6576. submitRequest.call(this, {
  6577. Action: 'name/cos:DeleteBucketOrigin',
  6578. method: 'DELETE',
  6579. Bucket: params.Bucket,
  6580. Region: params.Region,
  6581. headers: params.Headers,
  6582. action: 'origin'
  6583. }, function (err, data) {
  6584. if (err && err.statusCode === 204) {
  6585. return callback(null, { statusCode: err.statusCode });
  6586. } else if (err) {
  6587. return callback(err);
  6588. }
  6589. callback(null, {
  6590. statusCode: data.statusCode,
  6591. headers: data.headers
  6592. });
  6593. });
  6594. }
  6595. /**
  6596. * 设置 Bucket 的日志记录
  6597. * @param {Object} params 参数对象,必须
  6598. * @param {String} params.Bucket Bucket名称,必须
  6599. * @param {String} params.Region 地域名称,必须
  6600. * @param {(Object|String)} params.BucketLoggingStatus 说明日志记录配置的状态,如果无子节点信息则意为关闭日志记录,必须
  6601. * @param {Function} callback 回调函数,必须
  6602. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6603. * @return {Object} data 返回数据
  6604. */
  6605. function putBucketLogging(params, callback) {
  6606. var xml = util.json2xml({
  6607. BucketLoggingStatus: params['BucketLoggingStatus'] || ''
  6608. });
  6609. var headers = params.Headers;
  6610. headers['Content-Type'] = 'application/xml';
  6611. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6612. submitRequest.call(this, {
  6613. Action: 'name/cos:PutBucketLogging',
  6614. method: 'PUT',
  6615. Bucket: params.Bucket,
  6616. Region: params.Region,
  6617. body: xml,
  6618. action: 'logging',
  6619. headers: headers
  6620. }, function (err, data) {
  6621. if (err && err.statusCode === 204) {
  6622. return callback(null, { statusCode: err.statusCode });
  6623. } else if (err) {
  6624. return callback(err);
  6625. }
  6626. callback(null, {
  6627. statusCode: data.statusCode,
  6628. headers: data.headers
  6629. });
  6630. });
  6631. }
  6632. /**
  6633. * 获取 Bucket 的日志记录
  6634. * @param {Object} params 参数对象,必须
  6635. * @param {String} params.Bucket Bucket名称,必须
  6636. * @param {String} params.Region 地域名称,必须
  6637. * @param {Function} callback 回调函数,必须
  6638. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6639. * @return {Object} data 返回数据
  6640. */
  6641. function getBucketLogging(params, callback) {
  6642. submitRequest.call(this, {
  6643. Action: 'name/cos:GetBucketLogging',
  6644. method: 'GET',
  6645. Bucket: params.Bucket,
  6646. Region: params.Region,
  6647. headers: params.Headers,
  6648. action: 'logging'
  6649. }, function (err, data) {
  6650. if (err) return callback(err);
  6651. callback(null, {
  6652. BucketLoggingStatus: data.BucketLoggingStatus,
  6653. statusCode: data.statusCode,
  6654. headers: data.headers
  6655. });
  6656. });
  6657. }
  6658. /**
  6659. * 创建/编辑 Bucket 的清单任务
  6660. * @param {Object} params 参数对象,必须
  6661. * @param {String} params.Bucket Bucket名称,必须
  6662. * @param {String} params.Region 地域名称,必须
  6663. * @param {String} params.Id 清单任务的名称,必须
  6664. * @param {Object} params.InventoryConfiguration 包含清单的配置参数,必须
  6665. * @param {Function} callback 回调函数,必须
  6666. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6667. * @return {Object} data 返回数据
  6668. */
  6669. function putBucketInventory(params, callback) {
  6670. var InventoryConfiguration = util.clone(params['InventoryConfiguration']);
  6671. if (InventoryConfiguration.OptionalFields) {
  6672. var Field = InventoryConfiguration.OptionalFields || [];
  6673. InventoryConfiguration.OptionalFields = {
  6674. Field: Field
  6675. };
  6676. }
  6677. if (InventoryConfiguration.Destination && InventoryConfiguration.Destination.COSBucketDestination && InventoryConfiguration.Destination.COSBucketDestination.Encryption) {
  6678. var Encryption = InventoryConfiguration.Destination.COSBucketDestination.Encryption;
  6679. if (Object.keys(Encryption).indexOf('SSECOS') > -1) {
  6680. Encryption['SSE-COS'] = Encryption['SSECOS'];
  6681. delete Encryption['SSECOS'];
  6682. }
  6683. }
  6684. var xml = util.json2xml({
  6685. InventoryConfiguration: InventoryConfiguration
  6686. });
  6687. var headers = params.Headers;
  6688. headers['Content-Type'] = 'application/xml';
  6689. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6690. submitRequest.call(this, {
  6691. Action: 'name/cos:PutBucketInventory',
  6692. method: 'PUT',
  6693. Bucket: params.Bucket,
  6694. Region: params.Region,
  6695. body: xml,
  6696. action: 'inventory',
  6697. qs: {
  6698. id: params['Id']
  6699. },
  6700. headers: headers
  6701. }, function (err, data) {
  6702. if (err && err.statusCode === 204) {
  6703. return callback(null, { statusCode: err.statusCode });
  6704. } else if (err) {
  6705. return callback(err);
  6706. }
  6707. callback(null, {
  6708. statusCode: data.statusCode,
  6709. headers: data.headers
  6710. });
  6711. });
  6712. }
  6713. /**
  6714. * 获取 Bucket 的清单任务信息
  6715. * @param {Object} params 参数对象,必须
  6716. * @param {String} params.Bucket Bucket名称,必须
  6717. * @param {String} params.Region 地域名称,必须
  6718. * @param {String} params.Id 清单任务的名称,必须
  6719. * @param {Function} callback 回调函数,必须
  6720. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6721. * @return {Object} data 返回数据
  6722. */
  6723. function getBucketInventory(params, callback) {
  6724. submitRequest.call(this, {
  6725. Action: 'name/cos:GetBucketInventory',
  6726. method: 'GET',
  6727. Bucket: params.Bucket,
  6728. Region: params.Region,
  6729. headers: params.Headers,
  6730. action: 'inventory',
  6731. qs: {
  6732. id: params['Id']
  6733. }
  6734. }, function (err, data) {
  6735. if (err) return callback(err);
  6736. var InventoryConfiguration = data['InventoryConfiguration'];
  6737. if (InventoryConfiguration && InventoryConfiguration.OptionalFields && InventoryConfiguration.OptionalFields.Field) {
  6738. var Field = InventoryConfiguration.OptionalFields.Field;
  6739. if (!util.isArray(Field)) {
  6740. Field = [Field];
  6741. }
  6742. InventoryConfiguration.OptionalFields = Field;
  6743. }
  6744. if (InventoryConfiguration.Destination && InventoryConfiguration.Destination.COSBucketDestination && InventoryConfiguration.Destination.COSBucketDestination.Encryption) {
  6745. var Encryption = InventoryConfiguration.Destination.COSBucketDestination.Encryption;
  6746. if (Object.keys(Encryption).indexOf('SSE-COS') > -1) {
  6747. Encryption['SSECOS'] = Encryption['SSE-COS'];
  6748. delete Encryption['SSE-COS'];
  6749. }
  6750. }
  6751. callback(null, {
  6752. InventoryConfiguration: InventoryConfiguration,
  6753. statusCode: data.statusCode,
  6754. headers: data.headers
  6755. });
  6756. });
  6757. }
  6758. /**
  6759. * 获取 Bucket 的清单任务信息
  6760. * @param {Object} params 参数对象,必须
  6761. * @param {String} params.Bucket Bucket名称,必须
  6762. * @param {String} params.Region 地域名称,必须
  6763. * @param {String} params.ContinuationToken 当 COS 响应体中 IsTruncated 为 true,且 NextContinuationToken 节点中存在参数值时,您可以将这个参数作为 continuation-token 参数值,以获取下一页的清单任务信息,非必须
  6764. * @param {Function} callback 回调函数,必须
  6765. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6766. * @return {Object} data 返回数据
  6767. */
  6768. function listBucketInventory(params, callback) {
  6769. submitRequest.call(this, {
  6770. Action: 'name/cos:ListBucketInventory',
  6771. method: 'GET',
  6772. Bucket: params.Bucket,
  6773. Region: params.Region,
  6774. headers: params.Headers,
  6775. action: 'inventory',
  6776. qs: {
  6777. 'continuation-token': params['ContinuationToken']
  6778. }
  6779. }, function (err, data) {
  6780. if (err) return callback(err);
  6781. var ListInventoryConfigurationResult = data['ListInventoryConfigurationResult'];
  6782. var InventoryConfigurations = ListInventoryConfigurationResult.InventoryConfiguration || [];
  6783. InventoryConfigurations = util.isArray(InventoryConfigurations) ? InventoryConfigurations : [InventoryConfigurations];
  6784. delete ListInventoryConfigurationResult['InventoryConfiguration'];
  6785. util.each(InventoryConfigurations, function (InventoryConfiguration) {
  6786. if (InventoryConfiguration && InventoryConfiguration.OptionalFields && InventoryConfiguration.OptionalFields.Field) {
  6787. var Field = InventoryConfiguration.OptionalFields.Field;
  6788. if (!util.isArray(Field)) {
  6789. Field = [Field];
  6790. }
  6791. InventoryConfiguration.OptionalFields = Field;
  6792. }
  6793. if (InventoryConfiguration.Destination && InventoryConfiguration.Destination.COSBucketDestination && InventoryConfiguration.Destination.COSBucketDestination.Encryption) {
  6794. var Encryption = InventoryConfiguration.Destination.COSBucketDestination.Encryption;
  6795. if (Object.keys(Encryption).indexOf('SSE-COS') > -1) {
  6796. Encryption['SSECOS'] = Encryption['SSE-COS'];
  6797. delete Encryption['SSE-COS'];
  6798. }
  6799. }
  6800. });
  6801. ListInventoryConfigurationResult.InventoryConfigurations = InventoryConfigurations;
  6802. util.extend(ListInventoryConfigurationResult, {
  6803. statusCode: data.statusCode,
  6804. headers: data.headers
  6805. });
  6806. callback(null, ListInventoryConfigurationResult);
  6807. });
  6808. }
  6809. /**
  6810. * 删除 Bucket 的清单任务
  6811. * @param {Object} params 参数对象,必须
  6812. * @param {String} params.Bucket Bucket名称,必须
  6813. * @param {String} params.Region 地域名称,必须
  6814. * @param {String} params.Id 清单任务的名称,必须
  6815. * @param {Function} callback 回调函数,必须
  6816. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6817. * @return {Object} data 返回数据
  6818. */
  6819. function deleteBucketInventory(params, callback) {
  6820. submitRequest.call(this, {
  6821. Action: 'name/cos:DeleteBucketInventory',
  6822. method: 'DELETE',
  6823. Bucket: params.Bucket,
  6824. Region: params.Region,
  6825. headers: params.Headers,
  6826. action: 'inventory',
  6827. qs: {
  6828. id: params['Id']
  6829. }
  6830. }, function (err, data) {
  6831. if (err && err.statusCode === 204) {
  6832. return callback(null, { statusCode: err.statusCode });
  6833. } else if (err) {
  6834. return callback(err);
  6835. }
  6836. callback(null, {
  6837. statusCode: data.statusCode,
  6838. headers: data.headers
  6839. });
  6840. });
  6841. }
  6842. /* 全球加速 */
  6843. function putBucketAccelerate(params, callback) {
  6844. if (!params['AccelerateConfiguration']) {
  6845. callback(util.error(new Error('missing param AccelerateConfiguration')));
  6846. return;
  6847. }
  6848. var configuration = { AccelerateConfiguration: params.AccelerateConfiguration || {} };
  6849. var xml = util.json2xml(configuration);
  6850. var headers = {};
  6851. headers['Content-Type'] = 'application/xml';
  6852. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6853. submitRequest.call(this, {
  6854. Action: 'name/cos:PutBucketAccelerate',
  6855. method: 'PUT',
  6856. Bucket: params.Bucket,
  6857. Region: params.Region,
  6858. body: xml,
  6859. action: 'accelerate',
  6860. headers: headers
  6861. }, function (err, data) {
  6862. if (err) return callback(err);
  6863. callback(null, {
  6864. statusCode: data.statusCode,
  6865. headers: data.headers
  6866. });
  6867. });
  6868. }
  6869. function getBucketAccelerate(params, callback) {
  6870. submitRequest.call(this, {
  6871. Action: 'name/cos:GetBucketAccelerate',
  6872. method: 'GET',
  6873. Bucket: params.Bucket,
  6874. Region: params.Region,
  6875. action: 'accelerate'
  6876. }, function (err, data) {
  6877. if (!err) {
  6878. !data.AccelerateConfiguration && (data.AccelerateConfiguration = {});
  6879. }
  6880. callback(err, data);
  6881. });
  6882. }
  6883. function putBucketEncryption(params, callback) {
  6884. var conf = params.ServerSideEncryptionConfiguration || {};
  6885. var Rules = conf.Rule || conf.Rules || [];
  6886. var xml = util.json2xml({ ServerSideEncryptionConfiguration: { Rule: Rules } });
  6887. var headers = params.Headers;
  6888. headers['Content-Type'] = 'application/xml';
  6889. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  6890. submitRequest.call(this, {
  6891. Action: 'name/cos:PutBucketEncryption',
  6892. method: 'PUT',
  6893. Bucket: params.Bucket,
  6894. Region: params.Region,
  6895. body: xml,
  6896. action: 'encryption',
  6897. headers: headers
  6898. }, function (err, data) {
  6899. if (err && err.statusCode === 204) {
  6900. return callback(null, { statusCode: err.statusCode });
  6901. } else if (err) {
  6902. return callback(err);
  6903. }
  6904. callback(null, {
  6905. statusCode: data.statusCode,
  6906. headers: data.headers
  6907. });
  6908. });
  6909. }
  6910. function getBucketEncryption(params, callback) {
  6911. submitRequest.call(this, {
  6912. Action: 'name/cos:GetBucketEncryption',
  6913. method: 'GET',
  6914. Bucket: params.Bucket,
  6915. Region: params.Region,
  6916. headers: params.Headers,
  6917. action: 'encryption'
  6918. }, function (err, data) {
  6919. if (err) {
  6920. if (err.statusCode === 404 && err.code === 'NoSuchEncryptionConfiguration') {
  6921. var result = {
  6922. EncryptionConfiguration: { Rules: [] },
  6923. statusCode: err.statusCode
  6924. };
  6925. err.headers && (result.headers = err.headers);
  6926. callback(null, result);
  6927. } else {
  6928. callback(err);
  6929. }
  6930. return;
  6931. }
  6932. var Rules = util.makeArray(data.EncryptionConfiguration && data.EncryptionConfiguration.Rule || []);
  6933. data.EncryptionConfiguration = { Rules: Rules };
  6934. callback(err, data);
  6935. });
  6936. }
  6937. function deleteBucketEncryption(params, callback) {
  6938. submitRequest.call(this, {
  6939. Action: 'name/cos:DeleteBucketReplication',
  6940. method: 'DELETE',
  6941. Bucket: params.Bucket,
  6942. Region: params.Region,
  6943. headers: params.Headers,
  6944. action: 'encryption'
  6945. }, function (err, data) {
  6946. if (err && err.statusCode === 204) {
  6947. return callback(null, { statusCode: err.statusCode });
  6948. } else if (err) {
  6949. return callback(err);
  6950. }
  6951. callback(null, {
  6952. statusCode: data.statusCode,
  6953. headers: data.headers
  6954. });
  6955. });
  6956. }
  6957. // Object 相关
  6958. /**
  6959. * 取回对应Object的元数据,Head的权限与Get的权限一致
  6960. * @param {Object} params 参数对象,必须
  6961. * @param {String} params.Bucket Bucket名称,必须
  6962. * @param {String} params.Region 地域名称,必须
  6963. * @param {String} params.Key 文件名称,必须
  6964. * @param {String} params.IfModifiedSince 当Object在指定时间后被修改,则返回对应Object元信息,否则返回304,非必须
  6965. * @param {Function} callback 回调函数,必须
  6966. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  6967. * @return {Object} data 为指定 object 的元数据,如果设置了 IfModifiedSince ,且文件未修改,则返回一个对象,NotModified 属性为 true
  6968. * @return {Boolean} data.NotModified 是否在 IfModifiedSince 时间点之后未修改该 object,则为 true
  6969. */
  6970. function headObject(params, callback) {
  6971. submitRequest.call(this, {
  6972. Action: 'name/cos:HeadObject',
  6973. method: 'HEAD',
  6974. Bucket: params.Bucket,
  6975. Region: params.Region,
  6976. Key: params.Key,
  6977. VersionId: params.VersionId,
  6978. headers: params.Headers
  6979. }, function (err, data) {
  6980. if (err) {
  6981. var statusCode = err.statusCode;
  6982. if (params.Headers['If-Modified-Since'] && statusCode && statusCode === 304) {
  6983. return callback(null, {
  6984. NotModified: true,
  6985. statusCode: statusCode
  6986. });
  6987. }
  6988. return callback(err);
  6989. }
  6990. data.ETag = util.attr(data.headers, 'etag', '');
  6991. callback(null, data);
  6992. });
  6993. }
  6994. function listObjectVersions(params, callback) {
  6995. var reqParams = {};
  6996. reqParams['prefix'] = params['Prefix'] || '';
  6997. reqParams['delimiter'] = params['Delimiter'];
  6998. reqParams['key-marker'] = params['KeyMarker'];
  6999. reqParams['version-id-marker'] = params['VersionIdMarker'];
  7000. reqParams['max-keys'] = params['MaxKeys'];
  7001. reqParams['encoding-type'] = params['EncodingType'];
  7002. submitRequest.call(this, {
  7003. Action: 'name/cos:GetBucketObjectVersions',
  7004. ResourceKey: reqParams['prefix'],
  7005. method: 'GET',
  7006. Bucket: params.Bucket,
  7007. Region: params.Region,
  7008. headers: params.Headers,
  7009. qs: reqParams,
  7010. action: 'versions'
  7011. }, function (err, data) {
  7012. if (err) return callback(err);
  7013. var ListVersionsResult = data.ListVersionsResult || {};
  7014. var DeleteMarkers = ListVersionsResult.DeleteMarker || [];
  7015. DeleteMarkers = util.isArray(DeleteMarkers) ? DeleteMarkers : [DeleteMarkers];
  7016. var Versions = ListVersionsResult.Version || [];
  7017. Versions = util.isArray(Versions) ? Versions : [Versions];
  7018. var result = util.clone(ListVersionsResult);
  7019. delete result.DeleteMarker;
  7020. delete result.Version;
  7021. util.extend(result, {
  7022. DeleteMarkers: DeleteMarkers,
  7023. Versions: Versions,
  7024. statusCode: data.statusCode,
  7025. headers: data.headers
  7026. });
  7027. callback(null, result);
  7028. });
  7029. }
  7030. /**
  7031. * 下载 object
  7032. * @param {Object} params 参数对象,必须
  7033. * @param {String} params.Bucket Bucket名称,必须
  7034. * @param {String} params.Region 地域名称,必须
  7035. * @param {String} params.Key 文件名称,必须
  7036. * @param {WriteStream} params.Output 文件写入流,非必须
  7037. * @param {String} params.IfModifiedSince 当Object在指定时间后被修改,则返回对应Object元信息,否则返回304,非必须
  7038. * @param {String} params.IfUnmodifiedSince 如果文件修改时间早于或等于指定时间,才返回文件内容。否则返回 412 (precondition failed),非必须
  7039. * @param {String} params.IfMatch 当 ETag 与指定的内容一致,才返回文件。否则返回 412 (precondition failed),非必须
  7040. * @param {String} params.IfNoneMatch 当 ETag 与指定的内容不一致,才返回文件。否则返回304 (not modified),非必须
  7041. * @param {String} params.ResponseContentType 设置返回头部中的 Content-Type 参数,非必须
  7042. * @param {String} params.ResponseContentLanguage 设置返回头部中的 Content-Language 参数,非必须
  7043. * @param {String} params.ResponseExpires 设置返回头部中的 Content-Expires 参数,非必须
  7044. * @param {String} params.ResponseCacheControl 设置返回头部中的 Cache-Control 参数,非必须
  7045. * @param {String} params.ResponseContentDisposition 设置返回头部中的 Content-Disposition 参数,非必须
  7046. * @param {String} params.ResponseContentEncoding 设置返回头部中的 Content-Encoding 参数,非必须
  7047. * @param {Function} callback 回调函数,必须
  7048. * @param {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7049. * @param {Object} data 为对应的 object 数据,包括 body 和 headers
  7050. */
  7051. function getObject(params, callback) {
  7052. var reqParams = params.Query || {};
  7053. var reqParamsStr = params.QueryString || '';
  7054. var onProgress = util.throttleOnProgress.call(this, 0, params.onProgress);
  7055. reqParams['response-content-type'] = params['ResponseContentType'];
  7056. reqParams['response-content-language'] = params['ResponseContentLanguage'];
  7057. reqParams['response-expires'] = params['ResponseExpires'];
  7058. reqParams['response-cache-control'] = params['ResponseCacheControl'];
  7059. reqParams['response-content-disposition'] = params['ResponseContentDisposition'];
  7060. reqParams['response-content-encoding'] = params['ResponseContentEncoding'];
  7061. // 如果用户自己传入了 output
  7062. submitRequest.call(this, {
  7063. Action: 'name/cos:GetObject',
  7064. method: 'GET',
  7065. Bucket: params.Bucket,
  7066. Region: params.Region,
  7067. Key: params.Key,
  7068. VersionId: params.VersionId,
  7069. DataType: params.DataType,
  7070. headers: params.Headers,
  7071. qs: reqParams,
  7072. qsStr: reqParamsStr,
  7073. rawBody: true,
  7074. onDownloadProgress: onProgress
  7075. }, function (err, data) {
  7076. onProgress(null, true);
  7077. if (err) {
  7078. var statusCode = err.statusCode;
  7079. if (params.Headers['If-Modified-Since'] && statusCode && statusCode === 304) {
  7080. return callback(null, {
  7081. NotModified: true
  7082. });
  7083. }
  7084. return callback(err);
  7085. }
  7086. callback(null, {
  7087. Body: data.body,
  7088. ETag: util.attr(data.headers, 'etag', ''),
  7089. statusCode: data.statusCode,
  7090. headers: data.headers
  7091. });
  7092. });
  7093. }
  7094. /**
  7095. * 上传 object
  7096. * @param {Object} params 参数对象,必须
  7097. * @param {String} params.Bucket Bucket名称,必须
  7098. * @param {String} params.Region 地域名称,必须
  7099. * @param {String} params.Key 文件名称,必须
  7100. * @param {File || Blob || String} params.Body 上传文件对象或字符串,必须
  7101. * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
  7102. * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须
  7103. * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
  7104. * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须
  7105. * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
  7106. * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
  7107. * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
  7108. * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须
  7109. * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  7110. * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  7111. * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  7112. * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  7113. * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须
  7114. * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须
  7115. * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须
  7116. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  7117. * @param {Function} params.onProgress 上传进度回调函数
  7118. * @param {Function} callback 回调函数,必须
  7119. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7120. * @return {Object} data 为对应的 object 数据
  7121. * @return {String} data.ETag 为对应上传文件的 ETag 值
  7122. */
  7123. function putObject(params, callback) {
  7124. var self = this;
  7125. var FileSize = params.ContentLength;
  7126. var onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
  7127. // 特殊处理 Cache-Control、Content-Type,避免代理更改这两个字段导致写入到 Object 属性里
  7128. var headers = params.Headers;
  7129. if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
  7130. if (!headers['Content-Type'] && !headers['content-type']) headers['Content-Type'] = params.Body && params.Body.type || '';
  7131. var needCalcMd5 = params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5 || self.options.UploadCheckContentMd5;
  7132. util.getBodyMd5(needCalcMd5, params.Body, function (md5) {
  7133. if (md5) {
  7134. if (self.options.UploadCheckContentMd5) headers['Content-MD5'] = util.binaryBase64(md5);
  7135. if (params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5) headers['x-cos-meta-md5'] = md5;
  7136. }
  7137. if (params.ContentLength !== undefined) headers['Content-Length'] = params.ContentLength;
  7138. onProgress(null, true); // 任务状态开始 uploading
  7139. submitRequest.call(self, {
  7140. Action: 'name/cos:PutObject',
  7141. TaskId: params.TaskId,
  7142. method: 'PUT',
  7143. Bucket: params.Bucket,
  7144. Region: params.Region,
  7145. Key: params.Key,
  7146. headers: params.Headers,
  7147. qs: params.Query,
  7148. body: params.Body,
  7149. onProgress: onProgress
  7150. }, function (err, data) {
  7151. if (err) {
  7152. onProgress(null, true);
  7153. return callback(err);
  7154. }
  7155. onProgress({ loaded: FileSize, total: FileSize }, true);
  7156. var url = getUrl({
  7157. ForcePathStyle: self.options.ForcePathStyle,
  7158. protocol: self.options.Protocol,
  7159. domain: self.options.Domain,
  7160. bucket: params.Bucket,
  7161. region: !self.options.UseAccelerate ? params.Region : 'accelerate',
  7162. object: params.Key
  7163. });
  7164. url = url.substr(url.indexOf('://') + 3);
  7165. data.Location = url;
  7166. data.ETag = util.attr(data.headers, 'etag', '');
  7167. callback(null, data);
  7168. });
  7169. }, params.onHashProgress);
  7170. }
  7171. /**
  7172. * 删除 object
  7173. * @param {Object} params 参数对象,必须
  7174. * @param {String} params.Bucket Bucket名称,必须
  7175. * @param {String} params.Region 地域名称,必须
  7176. * @param {String} params.Key object名称,必须
  7177. * @param {Function} callback 回调函数,必须
  7178. * @param {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7179. * @param {Object} data 删除操作成功之后返回的数据
  7180. */
  7181. function deleteObject(params, callback) {
  7182. submitRequest.call(this, {
  7183. Action: 'name/cos:DeleteObject',
  7184. method: 'DELETE',
  7185. Bucket: params.Bucket,
  7186. Region: params.Region,
  7187. Key: params.Key,
  7188. headers: params.Headers,
  7189. VersionId: params.VersionId,
  7190. action: params.Recursive ? 'recursive' : ''
  7191. }, function (err, data) {
  7192. if (err) {
  7193. var statusCode = err.statusCode;
  7194. if (statusCode && statusCode === 404) {
  7195. return callback(null, { BucketNotFound: true, statusCode: statusCode });
  7196. } else {
  7197. return callback(err);
  7198. }
  7199. }
  7200. callback(null, {
  7201. statusCode: data.statusCode,
  7202. headers: data.headers
  7203. });
  7204. });
  7205. }
  7206. /**
  7207. * 获取 object 的 权限列表
  7208. * @param {Object} params 参数对象,必须
  7209. * @param {String} params.Bucket Bucket名称,必须
  7210. * @param {String} params.Region 地域名称,必须
  7211. * @param {String} params.Key object名称,必须
  7212. * @param {Function} callback 回调函数,必须
  7213. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7214. * @return {Object} data 返回的数据
  7215. * @return {Object} data.AccessControlPolicy 权限列表
  7216. */
  7217. function getObjectAcl(params, callback) {
  7218. submitRequest.call(this, {
  7219. Action: 'name/cos:GetObjectACL',
  7220. method: 'GET',
  7221. Bucket: params.Bucket,
  7222. Region: params.Region,
  7223. Key: params.Key,
  7224. headers: params.Headers,
  7225. action: 'acl'
  7226. }, function (err, data) {
  7227. if (err) return callback(err);
  7228. var AccessControlPolicy = data.AccessControlPolicy || {};
  7229. var Owner = AccessControlPolicy.Owner || {};
  7230. var Grant = AccessControlPolicy.AccessControlList && AccessControlPolicy.AccessControlList.Grant || [];
  7231. Grant = util.isArray(Grant) ? Grant : [Grant];
  7232. var result = decodeAcl(AccessControlPolicy);
  7233. delete result.GrantWrite;
  7234. if (data.headers && data.headers['x-cos-acl']) {
  7235. result.ACL = data.headers['x-cos-acl'];
  7236. }
  7237. result = util.extend(result, {
  7238. Owner: Owner,
  7239. Grants: Grant,
  7240. statusCode: data.statusCode,
  7241. headers: data.headers
  7242. });
  7243. callback(null, result);
  7244. });
  7245. }
  7246. /**
  7247. * 设置 object 的 权限列表
  7248. * @param {Object} params 参数对象,必须
  7249. * @param {String} params.Bucket Bucket名称,必须
  7250. * @param {String} params.Region 地域名称,必须
  7251. * @param {String} params.Key object名称,必须
  7252. * @param {Function} callback 回调函数,必须
  7253. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7254. * @return {Object} data 返回的数据
  7255. */
  7256. function putObjectAcl(params, callback) {
  7257. var headers = params.Headers;
  7258. var xml = '';
  7259. if (params['AccessControlPolicy']) {
  7260. var AccessControlPolicy = util.clone(params['AccessControlPolicy'] || {});
  7261. var Grants = AccessControlPolicy.Grants || AccessControlPolicy.Grant;
  7262. Grants = util.isArray(Grants) ? Grants : [Grants];
  7263. delete AccessControlPolicy.Grant;
  7264. delete AccessControlPolicy.Grants;
  7265. AccessControlPolicy.AccessControlList = { Grant: Grants };
  7266. xml = util.json2xml({ AccessControlPolicy: AccessControlPolicy });
  7267. headers['Content-Type'] = 'application/xml';
  7268. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  7269. }
  7270. // Grant Header 去重
  7271. util.each(headers, function (val, key) {
  7272. if (key.indexOf('x-cos-grant-') === 0) {
  7273. headers[key] = uniqGrant(headers[key]);
  7274. }
  7275. });
  7276. submitRequest.call(this, {
  7277. Action: 'name/cos:PutObjectACL',
  7278. method: 'PUT',
  7279. Bucket: params.Bucket,
  7280. Region: params.Region,
  7281. Key: params.Key,
  7282. action: 'acl',
  7283. headers: headers,
  7284. body: xml
  7285. }, function (err, data) {
  7286. if (err) return callback(err);
  7287. callback(null, {
  7288. statusCode: data.statusCode,
  7289. headers: data.headers
  7290. });
  7291. });
  7292. }
  7293. /**
  7294. * Options Object请求实现跨域访问的预请求。即发出一个 OPTIONS 请求给服务器以确认是否可以进行跨域操作。
  7295. * @param {Object} params 参数对象,必须
  7296. * @param {String} params.Bucket Bucket名称,必须
  7297. * @param {String} params.Region 地域名称,必须
  7298. * @param {String} params.Key object名称,必须
  7299. * @param {Function} callback 回调函数,必须
  7300. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7301. * @return {Object} data 返回的数据
  7302. */
  7303. function optionsObject(params, callback) {
  7304. var headers = params.Headers;
  7305. headers['Origin'] = params['Origin'];
  7306. headers['Access-Control-Request-Method'] = params['AccessControlRequestMethod'];
  7307. headers['Access-Control-Request-Headers'] = params['AccessControlRequestHeaders'];
  7308. submitRequest.call(this, {
  7309. Action: 'name/cos:OptionsObject',
  7310. method: 'OPTIONS',
  7311. Bucket: params.Bucket,
  7312. Region: params.Region,
  7313. Key: params.Key,
  7314. headers: headers
  7315. }, function (err, data) {
  7316. if (err) {
  7317. if (err.statusCode && err.statusCode === 403) {
  7318. return callback(null, {
  7319. OptionsForbidden: true,
  7320. statusCode: err.statusCode
  7321. });
  7322. }
  7323. return callback(err);
  7324. }
  7325. var headers = data.headers || {};
  7326. callback(null, {
  7327. AccessControlAllowOrigin: headers['access-control-allow-origin'],
  7328. AccessControlAllowMethods: headers['access-control-allow-methods'],
  7329. AccessControlAllowHeaders: headers['access-control-allow-headers'],
  7330. AccessControlExposeHeaders: headers['access-control-expose-headers'],
  7331. AccessControlMaxAge: headers['access-control-max-age'],
  7332. statusCode: data.statusCode,
  7333. headers: data.headers
  7334. });
  7335. });
  7336. }
  7337. /**
  7338. * @param {Object} 参数列表
  7339. * @param {String} Bucket Bucket 名称
  7340. * @param {String} Region 地域名称
  7341. * @param {String} Key 文件名称
  7342. * @param {String} CopySource 源文件URL绝对路径,可以通过versionid子资源指定历史版本
  7343. * @param {String} ACL 允许用户自定义文件权限。有效值:private,public-read默认值:private。
  7344. * @param {String} GrantRead 赋予被授权者读的权限,格式 x-cos-grant-read: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
  7345. * @param {String} GrantWrite 赋予被授权者写的权限,格式 x-cos-grant-write: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
  7346. * @param {String} GrantFullControl 赋予被授权者读写权限,格式 x-cos-grant-full-control: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
  7347. * @param {String} MetadataDirective 是否拷贝元数据,枚举值:Copy, Replaced,默认值Copy。假如标记为Copy,忽略Header中的用户元数据信息直接复制;假如标记为Replaced,按Header信息修改元数据。当目标路径和原路径一致,即用户试图修改元数据时,必须为Replaced
  7348. * @param {String} CopySourceIfModifiedSince 当Object在指定时间后被修改,则执行操作,否则返回412。可与x-cos-copy-source-If-None-Match一起使用,与其他条件联合使用返回冲突。
  7349. * @param {String} CopySourceIfUnmodifiedSince 当Object在指定时间后未被修改,则执行操作,否则返回412。可与x-cos-copy-source-If-Match一起使用,与其他条件联合使用返回冲突。
  7350. * @param {String} CopySourceIfMatch 当Object的ETag和给定一致时,则执行操作,否则返回412。可与x-cos-copy-source-If-Unmodified-Since一起使用,与其他条件联合使用返回冲突。
  7351. * @param {String} CopySourceIfNoneMatch 当Object的ETag和给定不一致时,则执行操作,否则返回412。可与x-cos-copy-source-If-Modified-Since一起使用,与其他条件联合使用返回冲突。
  7352. * @param {String} StorageClass 存储级别,枚举值:存储级别,枚举值:Standard, Standard_IA,Archive;默认值:Standard
  7353. * @param {String} CacheControl 指定所有缓存机制在整个请求/响应链中必须服从的指令。
  7354. * @param {String} ContentDisposition MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件
  7355. * @param {String} ContentEncoding HTTP 中用来对「采用何种编码格式传输正文」进行协定的一对头部字段
  7356. * @param {String} ContentLength 设置响应消息的实体内容的大小,单位为字节
  7357. * @param {String} ContentType RFC 2616 中定义的 HTTP 请求内容类型(MIME),例如text/plain
  7358. * @param {String} Expect 请求的特定的服务器行为
  7359. * @param {String} Expires 响应过期的日期和时间
  7360. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  7361. * @param {String} ContentLanguage 指定内容语言
  7362. * @param {String} x-cos-meta-* 允许用户自定义的头部信息,将作为 Object 元数据返回。大小限制2K。
  7363. */
  7364. function putObjectCopy(params, callback) {
  7365. // 特殊处理 Cache-Control
  7366. var self = this;
  7367. var headers = params.Headers;
  7368. if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
  7369. var CopySource = params.CopySource || '';
  7370. var m = util.getSourceParams.call(this, CopySource);
  7371. if (!m) {
  7372. callback(util.error(new Error('CopySource format error')));
  7373. return;
  7374. }
  7375. var SourceBucket = m[1];
  7376. var SourceRegion = m[3];
  7377. var SourceKey = decodeURIComponent(m[4]);
  7378. submitRequest.call(this, {
  7379. Scope: [{
  7380. action: 'name/cos:GetObject',
  7381. bucket: SourceBucket,
  7382. region: SourceRegion,
  7383. prefix: SourceKey
  7384. }, {
  7385. action: 'name/cos:PutObject',
  7386. bucket: params.Bucket,
  7387. region: params.Region,
  7388. prefix: params.Key
  7389. }],
  7390. method: 'PUT',
  7391. Bucket: params.Bucket,
  7392. Region: params.Region,
  7393. Key: params.Key,
  7394. VersionId: params.VersionId,
  7395. headers: params.Headers
  7396. }, function (err, data) {
  7397. if (err) return callback(err);
  7398. var result = util.clone(data.CopyObjectResult || {});
  7399. var url = getUrl({
  7400. ForcePathStyle: self.options.ForcePathStyle,
  7401. protocol: self.options.Protocol,
  7402. domain: self.options.Domain,
  7403. bucket: params.Bucket,
  7404. region: params.Region,
  7405. object: params.Key,
  7406. isLocation: true
  7407. });
  7408. util.extend(result, {
  7409. Location: url,
  7410. statusCode: data.statusCode,
  7411. headers: data.headers
  7412. });
  7413. callback(null, result);
  7414. });
  7415. }
  7416. function uploadPartCopy(params, callback) {
  7417. var CopySource = params.CopySource || '';
  7418. var m = util.getSourceParams.call(this, CopySource);
  7419. if (!m) {
  7420. callback(util.error(new Error('CopySource format error')));
  7421. return;
  7422. }
  7423. var SourceBucket = m[1];
  7424. var SourceRegion = m[3];
  7425. var SourceKey = decodeURIComponent(m[4]);
  7426. submitRequest.call(this, {
  7427. Scope: [{
  7428. action: 'name/cos:GetObject',
  7429. bucket: SourceBucket,
  7430. region: SourceRegion,
  7431. prefix: SourceKey
  7432. }, {
  7433. action: 'name/cos:PutObject',
  7434. bucket: params.Bucket,
  7435. region: params.Region,
  7436. prefix: params.Key
  7437. }],
  7438. method: 'PUT',
  7439. Bucket: params.Bucket,
  7440. Region: params.Region,
  7441. Key: params.Key,
  7442. VersionId: params.VersionId,
  7443. qs: {
  7444. partNumber: params['PartNumber'],
  7445. uploadId: params['UploadId']
  7446. },
  7447. headers: params.Headers
  7448. }, function (err, data) {
  7449. if (err) return callback(err);
  7450. var result = util.clone(data.CopyPartResult || {});
  7451. util.extend(result, {
  7452. statusCode: data.statusCode,
  7453. headers: data.headers
  7454. });
  7455. callback(null, result);
  7456. });
  7457. }
  7458. function deleteMultipleObject(params, callback) {
  7459. var Objects = params.Objects || [];
  7460. var Quiet = params.Quiet;
  7461. Objects = util.isArray(Objects) ? Objects : [Objects];
  7462. var xml = util.json2xml({ Delete: { Object: Objects, Quiet: Quiet || false } });
  7463. var headers = params.Headers;
  7464. headers['Content-Type'] = 'application/xml';
  7465. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  7466. var Scope = util.map(Objects, function (v) {
  7467. return {
  7468. action: 'name/cos:DeleteObject',
  7469. bucket: params.Bucket,
  7470. region: params.Region,
  7471. prefix: v.Key
  7472. };
  7473. });
  7474. submitRequest.call(this, {
  7475. Scope: Scope,
  7476. method: 'POST',
  7477. Bucket: params.Bucket,
  7478. Region: params.Region,
  7479. body: xml,
  7480. action: 'delete',
  7481. headers: headers
  7482. }, function (err, data) {
  7483. if (err) return callback(err);
  7484. var DeleteResult = data.DeleteResult || {};
  7485. var Deleted = DeleteResult.Deleted || [];
  7486. var Errors = DeleteResult.Error || [];
  7487. Deleted = util.isArray(Deleted) ? Deleted : [Deleted];
  7488. Errors = util.isArray(Errors) ? Errors : [Errors];
  7489. var result = util.clone(DeleteResult);
  7490. util.extend(result, {
  7491. Error: Errors,
  7492. Deleted: Deleted,
  7493. statusCode: data.statusCode,
  7494. headers: data.headers
  7495. });
  7496. callback(null, result);
  7497. });
  7498. }
  7499. function restoreObject(params, callback) {
  7500. var headers = params.Headers;
  7501. if (!params['RestoreRequest']) {
  7502. callback(util.error(new Error('missing param RestoreRequest')));
  7503. return;
  7504. }
  7505. var RestoreRequest = params.RestoreRequest || {};
  7506. var xml = util.json2xml({ RestoreRequest: RestoreRequest });
  7507. headers['Content-Type'] = 'application/xml';
  7508. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  7509. submitRequest.call(this, {
  7510. Action: 'name/cos:RestoreObject',
  7511. method: 'POST',
  7512. Bucket: params.Bucket,
  7513. Region: params.Region,
  7514. Key: params.Key,
  7515. VersionId: params.VersionId,
  7516. body: xml,
  7517. action: 'restore',
  7518. headers: headers
  7519. }, callback);
  7520. }
  7521. /**
  7522. * 设置 Object 的标签
  7523. * @param {Object} params 参数对象,必须
  7524. * @param {String} params.Bucket Object名称,必须
  7525. * @param {String} params.Region 地域名称,必须
  7526. * @param {Array} params.TagSet 标签设置,必须
  7527. * @param {Function} callback 回调函数,必须
  7528. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
  7529. * @return {Object} data 返回数据
  7530. */
  7531. function putObjectTagging(params, callback) {
  7532. var Tagging = params['Tagging'] || {};
  7533. var Tags = Tagging.TagSet || Tagging.Tags || params['Tags'] || [];
  7534. Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
  7535. var xml = util.json2xml({ Tagging: { TagSet: { Tag: Tags } } });
  7536. var headers = params.Headers;
  7537. headers['Content-Type'] = 'application/xml';
  7538. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  7539. submitRequest.call(this, {
  7540. Action: 'name/cos:PutObjectTagging',
  7541. method: 'PUT',
  7542. Bucket: params.Bucket,
  7543. Key: params.Key,
  7544. Region: params.Region,
  7545. body: xml,
  7546. action: 'tagging',
  7547. headers: headers,
  7548. VersionId: params.VersionId
  7549. }, function (err, data) {
  7550. if (err && err.statusCode === 204) {
  7551. return callback(null, { statusCode: err.statusCode });
  7552. } else if (err) {
  7553. return callback(err);
  7554. }
  7555. callback(null, {
  7556. statusCode: data.statusCode,
  7557. headers: data.headers
  7558. });
  7559. });
  7560. }
  7561. /**
  7562. * 获取 Object 的标签设置
  7563. * @param {Object} params 参数对象,必须
  7564. * @param {String} params.Bucket Bucket名称,必须
  7565. * @param {String} params.Region 地域名称,必须
  7566. * @param {Function} callback 回调函数,必须
  7567. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
  7568. * @return {Object} data 返回数据
  7569. */
  7570. function getObjectTagging(params, callback) {
  7571. submitRequest.call(this, {
  7572. Action: 'name/cos:GetObjectTagging',
  7573. method: 'GET',
  7574. Key: params.Key,
  7575. Bucket: params.Bucket,
  7576. Region: params.Region,
  7577. headers: params.Headers,
  7578. action: 'tagging',
  7579. VersionId: params.VersionId
  7580. }, function (err, data) {
  7581. if (err) {
  7582. if (err.statusCode === 404 && err.error && (err.error === "Not Found" || err.error.Code === 'NoSuchTagSet')) {
  7583. var result = {
  7584. Tags: [],
  7585. statusCode: err.statusCode
  7586. };
  7587. err.headers && (result.headers = err.headers);
  7588. callback(null, result);
  7589. } else {
  7590. callback(err);
  7591. }
  7592. return;
  7593. }
  7594. var Tags = [];
  7595. try {
  7596. Tags = data.Tagging.TagSet.Tag || [];
  7597. } catch (e) {}
  7598. Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
  7599. callback(null, {
  7600. Tags: Tags,
  7601. statusCode: data.statusCode,
  7602. headers: data.headers
  7603. });
  7604. });
  7605. }
  7606. /**
  7607. * 删除 Object 的 标签设置
  7608. * @param {Object} params 参数对象,必须
  7609. * @param {String} params.Bucket Object名称,必须
  7610. * @param {String} params.Region 地域名称,必须
  7611. * @param {Function} callback 回调函数,必须
  7612. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
  7613. * @return {Object} data 返回的数据
  7614. */
  7615. function deleteObjectTagging(params, callback) {
  7616. submitRequest.call(this, {
  7617. Action: 'name/cos:DeleteObjectTagging',
  7618. method: 'DELETE',
  7619. Bucket: params.Bucket,
  7620. Region: params.Region,
  7621. Key: params.Key,
  7622. headers: params.Headers,
  7623. action: 'tagging',
  7624. VersionId: params.VersionId
  7625. }, function (err, data) {
  7626. if (err && err.statusCode === 204) {
  7627. return callback(null, { statusCode: err.statusCode });
  7628. } else if (err) {
  7629. return callback(err);
  7630. }
  7631. callback(null, {
  7632. statusCode: data.statusCode,
  7633. headers: data.headers
  7634. });
  7635. });
  7636. }
  7637. /**
  7638. * 使用 SQL 语句从指定对象(CSV 格式或者 JSON 格式)中检索内容
  7639. * @param {Object} params 参数对象,必须
  7640. * @param {String} params.Bucket Object名称,必须
  7641. * @param {String} params.Region 地域名称,必须
  7642. * @param {Object} params.SelectRequest 地域名称,必须
  7643. * @param {Function} callback 回调函数,必须
  7644. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
  7645. * @return {Object} data 返回的数据
  7646. */
  7647. function selectObjectContent(params, callback) {
  7648. var SelectType = params['SelectType'];
  7649. if (!SelectType) return callback(util.error(new Error('missing param SelectType')));
  7650. var SelectRequest = params['SelectRequest'] || {};
  7651. var xml = util.json2xml({ SelectRequest: SelectRequest });
  7652. var headers = params.Headers;
  7653. headers['Content-Type'] = 'application/xml';
  7654. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  7655. submitRequest.call(this, {
  7656. Action: 'name/cos:GetObject',
  7657. method: 'POST',
  7658. Bucket: params.Bucket,
  7659. Region: params.Region,
  7660. Key: params.Key,
  7661. headers: params.Headers,
  7662. action: 'select',
  7663. qs: {
  7664. 'select-type': params['SelectType']
  7665. },
  7666. VersionId: params.VersionId,
  7667. body: xml,
  7668. DataType: 'arraybuffer',
  7669. rawBody: true
  7670. }, function (err, data) {
  7671. if (err && err.statusCode === 204) {
  7672. return callback(null, { statusCode: err.statusCode });
  7673. } else if (err) {
  7674. return callback(err);
  7675. }
  7676. var result = util.parseSelectPayload(data.body);
  7677. callback(null, {
  7678. statusCode: data.statusCode,
  7679. headers: data.headers,
  7680. Body: result.body,
  7681. Payload: result.payload
  7682. });
  7683. });
  7684. }
  7685. // 分块上传
  7686. /**
  7687. * 初始化分块上传
  7688. * @param {Object} params 参数对象,必须
  7689. * @param {String} params.Bucket Bucket名称,必须
  7690. * @param {String} params.Region 地域名称,必须
  7691. * @param {String} params.Key object名称,必须
  7692. * @param {String} params.UploadId object名称,必须
  7693. * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
  7694. * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存 ,非必须
  7695. * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
  7696. * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
  7697. * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
  7698. * @param {String} params.ACL 允许用户自定义文件权限,非必须
  7699. * @param {String} params.GrantRead 赋予被授权者读的权限 ,非必须
  7700. * @param {String} params.GrantWrite 赋予被授权者写的权限 ,非必须
  7701. * @param {String} params.GrantFullControl 赋予被授权者读写权限 ,非必须
  7702. * @param {String} params.StorageClass 设置Object的存储级别,枚举值:Standard,Standard_IA,Archive,非必须
  7703. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  7704. * @param {Function} callback 回调函数,必须
  7705. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7706. * @return {Object} data 返回的数据
  7707. */
  7708. function multipartInit(params, callback) {
  7709. var self = this;
  7710. // 特殊处理 Cache-Control
  7711. var headers = params.Headers;
  7712. // 特殊处理 Cache-Control、Content-Type
  7713. if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
  7714. if (!headers['Content-Type'] && !headers['content-type']) headers['Content-Type'] = params.Body && params.Body.type || '';
  7715. util.getBodyMd5(params.Body && (params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5), params.Body, function (md5) {
  7716. if (md5) params.Headers['x-cos-meta-md5'] = md5;
  7717. submitRequest.call(self, {
  7718. Action: 'name/cos:InitiateMultipartUpload',
  7719. method: 'POST',
  7720. Bucket: params.Bucket,
  7721. Region: params.Region,
  7722. Key: params.Key,
  7723. action: 'uploads',
  7724. headers: params.Headers,
  7725. qs: params.Query
  7726. }, function (err, data) {
  7727. if (err) return callback(err);
  7728. data = util.clone(data || {});
  7729. if (data && data.InitiateMultipartUploadResult) {
  7730. return callback(null, util.extend(data.InitiateMultipartUploadResult, {
  7731. statusCode: data.statusCode,
  7732. headers: data.headers
  7733. }));
  7734. }
  7735. callback(null, data);
  7736. });
  7737. }, params.onHashProgress);
  7738. }
  7739. /**
  7740. * 分块上传
  7741. * @param {Object} params 参数对象,必须
  7742. * @param {String} params.Bucket Bucket名称,必须
  7743. * @param {String} params.Region 地域名称,必须
  7744. * @param {String} params.Key object名称,必须
  7745. * @param {File || Blob || String} params.Body 上传文件对象或字符串
  7746. * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),非必须
  7747. * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
  7748. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  7749. * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验值,非必须
  7750. * @param {Function} callback 回调函数,必须
  7751. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7752. * @return {Object} data 返回的数据
  7753. * @return {Object} data.ETag 返回的文件分块 sha1 值
  7754. */
  7755. function multipartUpload(params, callback) {
  7756. var self = this;
  7757. util.getFileSize('multipartUpload', params, function () {
  7758. util.getBodyMd5(self.options.UploadCheckContentMd5, params.Body, function (md5) {
  7759. if (md5) params.Headers['Content-MD5'] = util.binaryBase64(md5);
  7760. submitRequest.call(self, {
  7761. Action: 'name/cos:UploadPart',
  7762. TaskId: params.TaskId,
  7763. method: 'PUT',
  7764. Bucket: params.Bucket,
  7765. Region: params.Region,
  7766. Key: params.Key,
  7767. qs: {
  7768. partNumber: params['PartNumber'],
  7769. uploadId: params['UploadId']
  7770. },
  7771. headers: params.Headers,
  7772. onProgress: params.onProgress,
  7773. body: params.Body || null
  7774. }, function (err, data) {
  7775. if (err) return callback(err);
  7776. callback(null, {
  7777. ETag: util.attr(data.headers, 'etag', ''),
  7778. statusCode: data.statusCode,
  7779. headers: data.headers
  7780. });
  7781. });
  7782. });
  7783. });
  7784. }
  7785. /**
  7786. * 完成分块上传
  7787. * @param {Object} params 参数对象,必须
  7788. * @param {String} params.Bucket Bucket名称,必须
  7789. * @param {String} params.Region 地域名称,必须
  7790. * @param {String} params.Key object名称,必须
  7791. * @param {Array} params.Parts 分块信息列表,必须
  7792. * @param {String} params.Parts[i].PartNumber 块编号,必须
  7793. * @param {String} params.Parts[i].ETag 分块的 sha1 校验值
  7794. * @param {Function} callback 回调函数,必须
  7795. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7796. * @return {Object} data 返回的数据
  7797. * @return {Object} data.CompleteMultipartUpload 完成分块上传后的文件信息,包括Location, Bucket, Key 和 ETag
  7798. */
  7799. function multipartComplete(params, callback) {
  7800. var self = this;
  7801. var UploadId = params.UploadId;
  7802. var Parts = params['Parts'];
  7803. for (var i = 0, len = Parts.length; i < len; i++) {
  7804. if (Parts[i]['ETag'] && Parts[i]['ETag'].indexOf('"') === 0) {
  7805. continue;
  7806. }
  7807. Parts[i]['ETag'] = '"' + Parts[i]['ETag'] + '"';
  7808. }
  7809. var xml = util.json2xml({ CompleteMultipartUpload: { Part: Parts } });
  7810. // CSP/ceph CompleteMultipartUpload 接口 body 写死了限制 1MB,这里醉倒 10000 片时,xml 字符串去掉空格853KB
  7811. xml = xml.replace(/\n\s*/g, '');
  7812. var headers = params.Headers;
  7813. headers['Content-Type'] = 'application/xml';
  7814. headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
  7815. submitRequest.call(this, {
  7816. Action: 'name/cos:CompleteMultipartUpload',
  7817. method: 'POST',
  7818. Bucket: params.Bucket,
  7819. Region: params.Region,
  7820. Key: params.Key,
  7821. qs: {
  7822. uploadId: UploadId
  7823. },
  7824. body: xml,
  7825. headers: headers
  7826. }, function (err, data) {
  7827. if (err) return callback(err);
  7828. var url = getUrl({
  7829. ForcePathStyle: self.options.ForcePathStyle,
  7830. protocol: self.options.Protocol,
  7831. domain: self.options.Domain,
  7832. bucket: params.Bucket,
  7833. region: params.Region,
  7834. object: params.Key,
  7835. isLocation: true
  7836. });
  7837. var res = data.CompleteMultipartUploadResult || {};
  7838. if (res.ProcessResults) {
  7839. if (res && res.ProcessResults) {
  7840. res.UploadResult = {
  7841. OriginalInfo: {
  7842. Key: res.Key,
  7843. Location: url,
  7844. ETag: res.ETag,
  7845. ImageInfo: res.ImageInfo
  7846. },
  7847. ProcessResults: res.ProcessResults
  7848. };
  7849. delete res.ImageInfo;
  7850. delete res.ProcessResults;
  7851. }
  7852. }
  7853. var result = util.extend(res, {
  7854. Location: url,
  7855. statusCode: data.statusCode,
  7856. headers: data.headers
  7857. });
  7858. callback(null, result);
  7859. });
  7860. }
  7861. /**
  7862. * 分块上传任务列表查询
  7863. * @param {Object} params 参数对象,必须
  7864. * @param {String} params.Bucket Bucket名称,必须
  7865. * @param {String} params.Region 地域名称,必须
  7866. * @param {String} params.Delimiter 定界符为一个符号,如果有Prefix,则将Prefix到delimiter之间的相同路径归为一类,定义为Common Prefix,然后列出所有Common Prefix。如果没有Prefix,则从路径起点开始,非必须
  7867. * @param {String} params.EncodingType 规定返回值的编码方式,非必须
  7868. * @param {String} params.Prefix 前缀匹配,用来规定返回的文件前缀地址,非必须
  7869. * @param {String} params.MaxUploads 单次返回最大的条目数量,默认1000,非必须
  7870. * @param {String} params.KeyMarker 与upload-id-marker一起使用 </Br>当upload-id-marker未被指定时,ObjectName字母顺序大于key-marker的条目将被列出 </Br>当upload-id-marker被指定时,ObjectName字母顺序大于key-marker的条目被列出,ObjectName字母顺序等于key-marker同时UploadId大于upload-id-marker的条目将被列出,非必须
  7871. * @param {String} params.UploadIdMarker 与key-marker一起使用 </Br>当key-marker未被指定时,upload-id-marker将被忽略 </Br>当key-marker被指定时,ObjectName字母顺序大于key-marker的条目被列出,ObjectName字母顺序等于key-marker同时UploadId大于upload-id-marker的条目将被列出,非必须
  7872. * @param {Function} callback 回调函数,必须
  7873. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7874. * @return {Object} data 返回的数据
  7875. * @return {Object} data.ListMultipartUploadsResult 分块上传任务信息
  7876. */
  7877. function multipartList(params, callback) {
  7878. var reqParams = {};
  7879. reqParams['delimiter'] = params['Delimiter'];
  7880. reqParams['encoding-type'] = params['EncodingType'];
  7881. reqParams['prefix'] = params['Prefix'] || '';
  7882. reqParams['max-uploads'] = params['MaxUploads'];
  7883. reqParams['key-marker'] = params['KeyMarker'];
  7884. reqParams['upload-id-marker'] = params['UploadIdMarker'];
  7885. reqParams = util.clearKey(reqParams);
  7886. submitRequest.call(this, {
  7887. Action: 'name/cos:ListMultipartUploads',
  7888. ResourceKey: reqParams['prefix'],
  7889. method: 'GET',
  7890. Bucket: params.Bucket,
  7891. Region: params.Region,
  7892. headers: params.Headers,
  7893. qs: reqParams,
  7894. action: 'uploads'
  7895. }, function (err, data) {
  7896. if (err) return callback(err);
  7897. if (data && data.ListMultipartUploadsResult) {
  7898. var Upload = data.ListMultipartUploadsResult.Upload || [];
  7899. Upload = util.isArray(Upload) ? Upload : [Upload];
  7900. data.ListMultipartUploadsResult.Upload = Upload;
  7901. }
  7902. var result = util.clone(data.ListMultipartUploadsResult || {});
  7903. util.extend(result, {
  7904. statusCode: data.statusCode,
  7905. headers: data.headers
  7906. });
  7907. callback(null, result);
  7908. });
  7909. }
  7910. /**
  7911. * 上传的分块列表查询
  7912. * @param {Object} params 参数对象,必须
  7913. * @param {String} params.Bucket Bucket名称,必须
  7914. * @param {String} params.Region 地域名称,必须
  7915. * @param {String} params.Key object名称,必须
  7916. * @param {String} params.UploadId 标示本次分块上传的ID,必须
  7917. * @param {String} params.EncodingType 规定返回值的编码方式,非必须
  7918. * @param {String} params.MaxParts 单次返回最大的条目数量,默认1000,非必须
  7919. * @param {String} params.PartNumberMarker 默认以UTF-8二进制顺序列出条目,所有列出条目从marker开始,非必须
  7920. * @param {Function} callback 回调函数,必须
  7921. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7922. * @return {Object} data 返回的数据
  7923. * @return {Object} data.ListMultipartUploadsResult 分块信息
  7924. */
  7925. function multipartListPart(params, callback) {
  7926. var reqParams = {};
  7927. reqParams['uploadId'] = params['UploadId'];
  7928. reqParams['encoding-type'] = params['EncodingType'];
  7929. reqParams['max-parts'] = params['MaxParts'];
  7930. reqParams['part-number-marker'] = params['PartNumberMarker'];
  7931. submitRequest.call(this, {
  7932. Action: 'name/cos:ListParts',
  7933. method: 'GET',
  7934. Bucket: params.Bucket,
  7935. Region: params.Region,
  7936. Key: params.Key,
  7937. headers: params.Headers,
  7938. qs: reqParams
  7939. }, function (err, data) {
  7940. if (err) return callback(err);
  7941. var ListPartsResult = data.ListPartsResult || {};
  7942. var Part = ListPartsResult.Part || [];
  7943. Part = util.isArray(Part) ? Part : [Part];
  7944. ListPartsResult.Part = Part;
  7945. var result = util.clone(ListPartsResult);
  7946. util.extend(result, {
  7947. statusCode: data.statusCode,
  7948. headers: data.headers
  7949. });
  7950. callback(null, result);
  7951. });
  7952. }
  7953. /**
  7954. * 抛弃分块上传
  7955. * @param {Object} params 参数对象,必须
  7956. * @param {String} params.Bucket Bucket名称,必须
  7957. * @param {String} params.Region 地域名称,必须
  7958. * @param {String} params.Key object名称,必须
  7959. * @param {String} params.UploadId 标示本次分块上传的ID,必须
  7960. * @param {Function} callback 回调函数,必须
  7961. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7962. * @return {Object} data 返回的数据
  7963. */
  7964. function multipartAbort(params, callback) {
  7965. var reqParams = {};
  7966. reqParams['uploadId'] = params['UploadId'];
  7967. submitRequest.call(this, {
  7968. Action: 'name/cos:AbortMultipartUpload',
  7969. method: 'DELETE',
  7970. Bucket: params.Bucket,
  7971. Region: params.Region,
  7972. Key: params.Key,
  7973. headers: params.Headers,
  7974. qs: reqParams
  7975. }, function (err, data) {
  7976. if (err) return callback(err);
  7977. callback(null, {
  7978. statusCode: data.statusCode,
  7979. headers: data.headers
  7980. });
  7981. });
  7982. }
  7983. /**
  7984. * 抛弃分块上传
  7985. * @param {Object} params 参数对象,必须
  7986. * @param {String} params.Bucket Bucket名称,必须
  7987. * @param {String} params.Region 地域名称,必须
  7988. * @param {String} params.Key object名称,必须
  7989. * @param {String} params.UploadId 标示本次分块上传的ID,必须
  7990. * @param {Function} callback 回调函数,必须
  7991. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  7992. * @return {Object} data 返回的数据
  7993. */
  7994. function request(params, callback) {
  7995. submitRequest.call(this, {
  7996. method: params.Method,
  7997. Bucket: params.Bucket,
  7998. Region: params.Region,
  7999. Key: params.Key,
  8000. action: params.Action,
  8001. headers: params.Headers,
  8002. qs: params.Query,
  8003. body: params.Body,
  8004. Url: params.Url,
  8005. rawBody: params.RawBody,
  8006. DataType: params.DataType
  8007. }, function (err, data) {
  8008. if (err) return callback(err);
  8009. if (data && data.body) {
  8010. data.Body = data.body;
  8011. delete data.body;
  8012. }
  8013. callback(err, data);
  8014. });
  8015. }
  8016. /**
  8017. * 追加上传
  8018. * @param {Object} params 参数对象,必须
  8019. * @param {String} params.Bucket Bucket名称,必须
  8020. * @param {String} params.Region 地域名称,必须
  8021. * @param {String} params.Key object名称,必须
  8022. * @param {File || Blob || String} params.Body 上传文件对象或字符串
  8023. * @param {Number} params.Position 追加操作的起始点,单位为字节,必须
  8024. * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
  8025. * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须
  8026. * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
  8027. * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须
  8028. * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
  8029. * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
  8030. * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
  8031. * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须
  8032. * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  8033. * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  8034. * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  8035. * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
  8036. * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须
  8037. * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须
  8038. * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须
  8039. * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
  8040. * @param {Function} callback 回调函数,必须
  8041. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  8042. * @return {Object} data 返回的数据
  8043. */
  8044. function appendObject(params, callback) {
  8045. // 特殊处理 Cache-Control、Content-Type,避免代理更改这两个字段导致写入到 Object 属性里
  8046. var headers = params.Headers;
  8047. if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
  8048. if (!headers['Content-Type'] && !headers['content-type']) headers['Content-Type'] = params.Body && params.Body.type || '';
  8049. submitRequest.call(this, {
  8050. Action: 'name/cos:AppendObject',
  8051. method: 'POST',
  8052. Bucket: params.Bucket,
  8053. Region: params.Region,
  8054. action: 'append',
  8055. Key: params.Key,
  8056. body: params.Body,
  8057. qs: {
  8058. position: params.Position
  8059. },
  8060. headers: params.Headers
  8061. }, function (err, data) {
  8062. if (err) return callback(err);
  8063. callback(null, data);
  8064. });
  8065. }
  8066. /**
  8067. * 获取签名
  8068. * @param {Object} params 参数对象,必须
  8069. * @param {String} params.Method 请求方法,必须
  8070. * @param {String} params.Key object名称,必须
  8071. * @param {String} params.Expires 名超时时间,单位秒,可选
  8072. * @return {String} data 返回签名字符串
  8073. */
  8074. function getAuth(params) {
  8075. var self = this;
  8076. return util.getAuth({
  8077. SecretId: params.SecretId || this.options.SecretId || '',
  8078. SecretKey: params.SecretKey || this.options.SecretKey || '',
  8079. Bucket: params.Bucket,
  8080. Region: params.Region,
  8081. Method: params.Method,
  8082. Key: params.Key,
  8083. Query: params.Query,
  8084. Headers: params.Headers,
  8085. Expires: params.Expires,
  8086. UseRawKey: self.options.UseRawKey,
  8087. SystemClockOffset: self.options.SystemClockOffset
  8088. });
  8089. }
  8090. /**
  8091. * 获取文件下载链接
  8092. * @param {Object} params 参数对象,必须
  8093. * @param {String} params.Bucket Bucket名称,必须
  8094. * @param {String} params.Region 地域名称,必须
  8095. * @param {String} params.Key object名称,必须
  8096. * @param {String} params.Method 请求的方法,可选
  8097. * @param {String} params.Expires 签名超时时间,单位秒,可选
  8098. * @param {Function} callback 回调函数,必须
  8099. * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
  8100. * @return {Object} data 返回的数据
  8101. */
  8102. function getObjectUrl(params, callback) {
  8103. var self = this;
  8104. var useAccelerate = params.UseAccelerate === undefined ? self.options.UseAccelerate : params.UseAccelerate;
  8105. var url = getUrl({
  8106. ForcePathStyle: self.options.ForcePathStyle,
  8107. protocol: params.Protocol || self.options.Protocol,
  8108. domain: params.Domain || self.options.Domain,
  8109. bucket: params.Bucket,
  8110. region: useAccelerate ? 'accelerate' : params.Region,
  8111. object: params.Key
  8112. });
  8113. var queryParamsStr = '';
  8114. if (params.Query) {
  8115. queryParamsStr += util.obj2str(params.Query);
  8116. }
  8117. if (params.QueryString) {
  8118. queryParamsStr += (queryParamsStr ? '&' : '') + params.QueryString;
  8119. }
  8120. var syncUrl = url;
  8121. if (params.Sign !== undefined && !params.Sign) {
  8122. queryParamsStr && (syncUrl += '?' + queryParamsStr);
  8123. callback(null, { Url: syncUrl });
  8124. return syncUrl;
  8125. }
  8126. // 签名加上 Host,避免跨桶访问
  8127. var SignHost = getSignHost.call(this, { Bucket: params.Bucket, Region: params.Region, UseAccelerate: params.UseAccelerate, Url: url });
  8128. var AuthData = getAuthorizationAsync.call(this, {
  8129. Action: (params.Method || '').toUpperCase() === 'PUT' ? 'name/cos:PutObject' : 'name/cos:GetObject',
  8130. Bucket: params.Bucket || '',
  8131. Region: params.Region || '',
  8132. Method: params.Method || 'get',
  8133. Key: params.Key,
  8134. Expires: params.Expires,
  8135. Headers: params.Headers,
  8136. Query: params.Query,
  8137. SignHost: SignHost,
  8138. ForceSignHost: params.ForceSignHost === false ? false : self.options.ForceSignHost // getObjectUrl支持传参ForceSignHost
  8139. }, function (err, AuthData) {
  8140. if (!callback) return;
  8141. if (err) {
  8142. callback(err);
  8143. return;
  8144. }
  8145. // 兼容万象url qUrlParamList需要再encode一次
  8146. var replaceUrlParamList = function (url) {
  8147. var urlParams = url.match(/q-url-param-list.*?(?=&)/g)[0];
  8148. var encodedParams = 'q-url-param-list=' + encodeURIComponent(urlParams.replace(/q-url-param-list=/, '')).toLowerCase();
  8149. var reg = new RegExp(urlParams, 'g');
  8150. var replacedUrl = url.replace(reg, encodedParams);
  8151. return replacedUrl;
  8152. };
  8153. var signUrl = url;
  8154. signUrl += '?' + (AuthData.Authorization.indexOf('q-signature') > -1 ? replaceUrlParamList(AuthData.Authorization) : 'sign=' + encodeURIComponent(AuthData.Authorization));
  8155. AuthData.SecurityToken && (signUrl += '&x-cos-security-token=' + AuthData.SecurityToken);
  8156. AuthData.ClientIP && (signUrl += '&clientIP=' + AuthData.ClientIP);
  8157. AuthData.ClientUA && (signUrl += '&clientUA=' + AuthData.ClientUA);
  8158. AuthData.Token && (signUrl += '&token=' + AuthData.Token);
  8159. queryParamsStr && (signUrl += '&' + queryParamsStr);
  8160. setTimeout(function () {
  8161. callback(null, { Url: signUrl });
  8162. });
  8163. });
  8164. if (AuthData) {
  8165. syncUrl += '?' + AuthData.Authorization + (AuthData.SecurityToken ? '&x-cos-security-token=' + AuthData.SecurityToken : '');
  8166. queryParamsStr && (syncUrl += '&' + queryParamsStr);
  8167. } else {
  8168. queryParamsStr && (syncUrl += '?' + queryParamsStr);
  8169. }
  8170. return syncUrl;
  8171. }
  8172. /**
  8173. * 私有方法
  8174. */
  8175. function decodeAcl(AccessControlPolicy) {
  8176. var result = {
  8177. GrantFullControl: [],
  8178. GrantWrite: [],
  8179. GrantRead: [],
  8180. GrantReadAcp: [],
  8181. GrantWriteAcp: [],
  8182. ACL: ''
  8183. };
  8184. var GrantMap = {
  8185. 'FULL_CONTROL': 'GrantFullControl',
  8186. 'WRITE': 'GrantWrite',
  8187. 'READ': 'GrantRead',
  8188. 'READ_ACP': 'GrantReadAcp',
  8189. 'WRITE_ACP': 'GrantWriteAcp'
  8190. };
  8191. var AccessControlList = AccessControlPolicy && AccessControlPolicy.AccessControlList || {};
  8192. var Grant = AccessControlList.Grant;
  8193. if (Grant) {
  8194. Grant = util.isArray(Grant) ? Grant : [Grant];
  8195. }
  8196. var PublicAcl = { READ: 0, WRITE: 0, FULL_CONTROL: 0 };
  8197. Grant && Grant.length && util.each(Grant, function (item) {
  8198. if (item.Grantee.ID === 'qcs::cam::anyone:anyone' || item.Grantee.URI === 'http://cam.qcloud.com/groups/global/AllUsers') {
  8199. PublicAcl[item.Permission] = 1;
  8200. } else if (item.Grantee.ID !== AccessControlPolicy.Owner.ID) {
  8201. result[GrantMap[item.Permission]].push('id="' + item.Grantee.ID + '"');
  8202. }
  8203. });
  8204. if (PublicAcl.FULL_CONTROL || PublicAcl.WRITE && PublicAcl.READ) {
  8205. result.ACL = 'public-read-write';
  8206. } else if (PublicAcl.READ) {
  8207. result.ACL = 'public-read';
  8208. } else {
  8209. result.ACL = 'private';
  8210. }
  8211. util.each(GrantMap, function (item) {
  8212. result[item] = uniqGrant(result[item].join(','));
  8213. });
  8214. return result;
  8215. }
  8216. // Grant 去重
  8217. function uniqGrant(str) {
  8218. var arr = str.split(',');
  8219. var exist = {};
  8220. var i, item;
  8221. for (i = 0; i < arr.length;) {
  8222. item = arr[i].trim();
  8223. if (exist[item]) {
  8224. arr.splice(i, 1);
  8225. } else {
  8226. exist[item] = true;
  8227. arr[i] = item;
  8228. i++;
  8229. }
  8230. }
  8231. return arr.join(',');
  8232. }
  8233. // 生成操作 url
  8234. function getUrl(params) {
  8235. var region = params.region || '';
  8236. var longBucket = params.bucket || '';
  8237. var shortBucket = longBucket.substr(0, longBucket.lastIndexOf('-'));
  8238. var appId = longBucket.substr(longBucket.lastIndexOf('-') + 1);
  8239. var domain = params.domain;
  8240. var object = params.object;
  8241. if (typeof domain === 'function') {
  8242. domain = domain({ Bucket: longBucket, Region: region });
  8243. }
  8244. var protocol = params.protocol || (util.isBrowser && location.protocol === 'http:' ? 'http:' : 'https:');
  8245. if (!domain) {
  8246. if (['cn-south', 'cn-south-2', 'cn-north', 'cn-east', 'cn-southwest', 'sg'].indexOf(region) > -1) {
  8247. domain = '{Region}.myqcloud.com';
  8248. } else {
  8249. domain = 'cos.{Region}.myqcloud.com';
  8250. }
  8251. if (!params.ForcePathStyle) {
  8252. domain = '{Bucket}.' + domain;
  8253. }
  8254. }
  8255. domain = domain.replace(/\{\{AppId\}\}/ig, appId).replace(/\{\{Bucket\}\}/ig, shortBucket).replace(/\{\{Region\}\}/ig, region).replace(/\{\{.*?\}\}/ig, '');
  8256. domain = domain.replace(/\{AppId\}/ig, appId).replace(/\{BucketName\}/ig, shortBucket).replace(/\{Bucket\}/ig, longBucket).replace(/\{Region\}/ig, region).replace(/\{.*?\}/ig, '');
  8257. if (!/^[a-zA-Z]+:\/\//.test(domain)) {
  8258. domain = protocol + '//' + domain;
  8259. }
  8260. // 去掉域名最后的斜杆
  8261. if (domain.slice(-1) === '/') {
  8262. domain = domain.slice(0, -1);
  8263. }
  8264. var url = domain;
  8265. if (params.ForcePathStyle) {
  8266. url += '/' + longBucket;
  8267. }
  8268. url += '/';
  8269. if (object) {
  8270. url += util.camSafeUrlEncode(object).replace(/%2F/g, '/');
  8271. }
  8272. if (params.isLocation) {
  8273. url = url.replace(/^https?:\/\//, '');
  8274. }
  8275. return url;
  8276. }
  8277. var getSignHost = function (opt) {
  8278. if (!opt.Bucket || !opt.Region) return '';
  8279. var useAccelerate = opt.UseAccelerate === undefined ? this.options.UseAccelerate : opt.UseAccelerate;
  8280. var url = opt.Url || getUrl({
  8281. ForcePathStyle: this.options.ForcePathStyle,
  8282. protocol: this.options.Protocol,
  8283. domain: this.options.Domain,
  8284. bucket: opt.Bucket,
  8285. region: useAccelerate ? 'accelerate' : opt.Region
  8286. });
  8287. var urlHost = url.replace(/^https?:\/\/([^/]+)(\/.*)?$/, '$1');
  8288. var standardHostReg = new RegExp('^([a-z\\d-]+-\\d+\\.)?(cos|cosv6|ci|pic)\\.([a-z\\d-]+)\\.myqcloud\\.com$');
  8289. if (standardHostReg.test(urlHost)) return urlHost;
  8290. return '';
  8291. };
  8292. // 异步获取签名
  8293. function getAuthorizationAsync(params, callback) {
  8294. var headers = util.clone(params.Headers);
  8295. var headerHost = '';
  8296. util.each(headers, function (v, k) {
  8297. (v === '' || ['content-type', 'cache-control', 'expires'].indexOf(k.toLowerCase()) > -1) && delete headers[k];
  8298. if (k.toLowerCase() === 'host') headerHost = v;
  8299. });
  8300. // ForceSignHost明确传入false才不加入host签名
  8301. var forceSignHost = params.ForceSignHost === false ? false : true;
  8302. // Host 加入签名计算
  8303. if (!headerHost && params.SignHost && forceSignHost) headers.Host = params.SignHost;
  8304. // 获取凭证的回调,避免用户 callback 多次
  8305. var cbDone = false;
  8306. var cb = function (err, AuthData) {
  8307. if (cbDone) return;
  8308. cbDone = true;
  8309. if (AuthData && AuthData.XCosSecurityToken && !AuthData.SecurityToken) {
  8310. AuthData = util.clone(AuthData);
  8311. AuthData.SecurityToken = AuthData.XCosSecurityToken;
  8312. delete AuthData.XCosSecurityToken;
  8313. }
  8314. callback && callback(err, AuthData);
  8315. };
  8316. var self = this;
  8317. var Bucket = params.Bucket || '';
  8318. var Region = params.Region || '';
  8319. // PathName
  8320. var KeyName = params.Key || '';
  8321. if (self.options.ForcePathStyle && Bucket) {
  8322. KeyName = Bucket + '/' + KeyName;
  8323. }
  8324. var Pathname = '/' + KeyName;
  8325. // Action、ResourceKey
  8326. var StsData = {};
  8327. var Scope = params.Scope;
  8328. if (!Scope) {
  8329. var Action = params.Action || '';
  8330. var ResourceKey = params.ResourceKey || params.Key || '';
  8331. Scope = params.Scope || [{
  8332. action: Action,
  8333. bucket: Bucket,
  8334. region: Region,
  8335. prefix: ResourceKey
  8336. }];
  8337. }
  8338. var ScopeKey = util.md5(JSON.stringify(Scope));
  8339. // STS
  8340. self._StsCache = self._StsCache || [];
  8341. (function () {
  8342. var i, AuthData;
  8343. for (i = self._StsCache.length - 1; i >= 0; i--) {
  8344. AuthData = self._StsCache[i];
  8345. var compareTime = Math.round(util.getSkewTime(self.options.SystemClockOffset) / 1000) + 30;
  8346. if (AuthData.StartTime && compareTime < AuthData.StartTime || compareTime >= AuthData.ExpiredTime) {
  8347. self._StsCache.splice(i, 1);
  8348. continue;
  8349. }
  8350. if (!AuthData.ScopeLimit || AuthData.ScopeLimit && AuthData.ScopeKey === ScopeKey) {
  8351. StsData = AuthData;
  8352. break;
  8353. }
  8354. }
  8355. })();
  8356. var calcAuthByTmpKey = function () {
  8357. var KeyTime = '';
  8358. if (StsData.StartTime && params.Expires) KeyTime = StsData.StartTime + ';' + (StsData.StartTime + params.Expires * 1);else if (StsData.StartTime && StsData.ExpiredTime) KeyTime = StsData.StartTime + ';' + StsData.ExpiredTime;
  8359. var Authorization = util.getAuth({
  8360. SecretId: StsData.TmpSecretId,
  8361. SecretKey: StsData.TmpSecretKey,
  8362. Method: params.Method,
  8363. Pathname: Pathname,
  8364. Query: params.Query,
  8365. Headers: headers,
  8366. Expires: params.Expires,
  8367. UseRawKey: self.options.UseRawKey,
  8368. SystemClockOffset: self.options.SystemClockOffset,
  8369. KeyTime: KeyTime,
  8370. ForceSignHost: forceSignHost
  8371. });
  8372. var AuthData = {
  8373. Authorization: Authorization,
  8374. SecurityToken: StsData.SecurityToken || StsData.XCosSecurityToken || '',
  8375. Token: StsData.Token || '',
  8376. ClientIP: StsData.ClientIP || '',
  8377. ClientUA: StsData.ClientUA || ''
  8378. };
  8379. cb(null, AuthData);
  8380. };
  8381. var checkAuthError = function (AuthData) {
  8382. if (AuthData.Authorization) {
  8383. // 检查签名格式
  8384. var formatAllow = false;
  8385. var auth = AuthData.Authorization;
  8386. if (auth) {
  8387. if (auth.indexOf(' ') > -1) {
  8388. formatAllow = false;
  8389. } else if (auth.indexOf('q-sign-algorithm=') > -1 && auth.indexOf('q-ak=') > -1 && auth.indexOf('q-sign-time=') > -1 && auth.indexOf('q-key-time=') > -1 && auth.indexOf('q-url-param-list=') > -1) {
  8390. formatAllow = true;
  8391. } else {
  8392. try {
  8393. auth = atob(auth);
  8394. if (auth.indexOf('a=') > -1 && auth.indexOf('k=') > -1 && auth.indexOf('t=') > -1 && auth.indexOf('r=') > -1 && auth.indexOf('b=') > -1) {
  8395. formatAllow = true;
  8396. }
  8397. } catch (e) {}
  8398. }
  8399. }
  8400. if (!formatAllow) return util.error(new Error('getAuthorization callback params format error'));
  8401. } else {
  8402. if (!AuthData.TmpSecretId) return util.error(new Error('getAuthorization callback params missing "TmpSecretId"'));
  8403. if (!AuthData.TmpSecretKey) return util.error(new Error('getAuthorization callback params missing "TmpSecretKey"'));
  8404. if (!AuthData.SecurityToken && !AuthData.XCosSecurityToken) return util.error(new Error('getAuthorization callback params missing "SecurityToken"'));
  8405. if (!AuthData.ExpiredTime) return util.error(new Error('getAuthorization callback params missing "ExpiredTime"'));
  8406. if (AuthData.ExpiredTime && AuthData.ExpiredTime.toString().length !== 10) return util.error(new Error('getAuthorization callback params "ExpiredTime" should be 10 digits'));
  8407. if (AuthData.StartTime && AuthData.StartTime.toString().length !== 10) return util.error(new Error('getAuthorization callback params "StartTime" should be 10 StartTime'));
  8408. }
  8409. return false;
  8410. };
  8411. // 先判断是否有临时密钥
  8412. if (StsData.ExpiredTime && StsData.ExpiredTime - util.getSkewTime(self.options.SystemClockOffset) / 1000 > 60) {
  8413. // 如果缓存的临时密钥有效,并还有超过60秒有效期就直接使用
  8414. calcAuthByTmpKey();
  8415. } else if (self.options.getAuthorization) {
  8416. // 外部计算签名或获取临时密钥
  8417. self.options.getAuthorization.call(self, {
  8418. Bucket: Bucket,
  8419. Region: Region,
  8420. Method: params.Method,
  8421. Key: KeyName,
  8422. Pathname: Pathname,
  8423. Query: params.Query,
  8424. Headers: headers,
  8425. Scope: Scope,
  8426. SystemClockOffset: self.options.SystemClockOffset,
  8427. ForceSignHost: forceSignHost
  8428. }, function (AuthData) {
  8429. if (typeof AuthData === 'string') AuthData = { Authorization: AuthData };
  8430. var AuthError = checkAuthError(AuthData);
  8431. if (AuthError) return cb(AuthError);
  8432. if (AuthData.Authorization) {
  8433. cb(null, AuthData);
  8434. } else {
  8435. StsData = AuthData || {};
  8436. StsData.Scope = Scope;
  8437. StsData.ScopeKey = ScopeKey;
  8438. self._StsCache.push(StsData);
  8439. calcAuthByTmpKey();
  8440. }
  8441. });
  8442. } else if (self.options.getSTS) {
  8443. // 外部获取临时密钥
  8444. self.options.getSTS.call(self, {
  8445. Bucket: Bucket,
  8446. Region: Region
  8447. }, function (data) {
  8448. StsData = data || {};
  8449. StsData.Scope = Scope;
  8450. StsData.ScopeKey = ScopeKey;
  8451. if (!StsData.TmpSecretId) StsData.TmpSecretId = StsData.SecretId;
  8452. if (!StsData.TmpSecretKey) StsData.TmpSecretKey = StsData.SecretKey;
  8453. var AuthError = checkAuthError(StsData);
  8454. if (AuthError) return cb(AuthError);
  8455. self._StsCache.push(StsData);
  8456. calcAuthByTmpKey();
  8457. });
  8458. } else {
  8459. // 内部计算获取签名
  8460. return function () {
  8461. var Authorization = util.getAuth({
  8462. SecretId: params.SecretId || self.options.SecretId,
  8463. SecretKey: params.SecretKey || self.options.SecretKey,
  8464. Method: params.Method,
  8465. Pathname: Pathname,
  8466. Query: params.Query,
  8467. Headers: headers,
  8468. Expires: params.Expires,
  8469. UseRawKey: self.options.UseRawKey,
  8470. SystemClockOffset: self.options.SystemClockOffset,
  8471. ForceSignHost: forceSignHost
  8472. });
  8473. var AuthData = {
  8474. Authorization: Authorization,
  8475. SecurityToken: self.options.SecurityToken || self.options.XCosSecurityToken
  8476. };
  8477. cb(null, AuthData);
  8478. return AuthData;
  8479. }();
  8480. }
  8481. return '';
  8482. }
  8483. // 调整时间偏差
  8484. function allowRetry(err) {
  8485. var allowRetry = false;
  8486. var isTimeError = false;
  8487. var serverDate = err.headers && (err.headers.date || err.headers.Date) || err.error && err.error.ServerTime;
  8488. try {
  8489. var errorCode = err.error.Code;
  8490. var errorMessage = err.error.Message;
  8491. if (errorCode === 'RequestTimeTooSkewed' || errorCode === 'AccessDenied' && errorMessage === 'Request has expired') {
  8492. isTimeError = true;
  8493. }
  8494. } catch (e) {}
  8495. if (err) {
  8496. if (isTimeError && serverDate) {
  8497. var serverTime = Date.parse(serverDate);
  8498. if (this.options.CorrectClockSkew && Math.abs(util.getSkewTime(this.options.SystemClockOffset) - serverTime) >= 30000) {
  8499. console.error('error: Local time is too skewed.');
  8500. this.options.SystemClockOffset = serverTime - Date.now();
  8501. allowRetry = true;
  8502. }
  8503. } else if (Math.floor(err.statusCode / 100) === 5) {
  8504. allowRetry = true;
  8505. }
  8506. }
  8507. return allowRetry;
  8508. }
  8509. // 获取签名并发起请求
  8510. function submitRequest(params, callback) {
  8511. var self = this;
  8512. // 处理 headers
  8513. !params.headers && (params.headers = {});
  8514. // 处理 query
  8515. !params.qs && (params.qs = {});
  8516. params.VersionId && (params.qs.versionId = params.VersionId);
  8517. params.qs = util.clearKey(params.qs);
  8518. // 清理 undefined 和 null 字段
  8519. params.headers && (params.headers = util.clearKey(params.headers));
  8520. params.qs && (params.qs = util.clearKey(params.qs));
  8521. var Query = util.clone(params.qs);
  8522. params.action && (Query[params.action] = '');
  8523. var paramsUrl = params.url || params.Url;
  8524. var SignHost = params.SignHost || getSignHost.call(this, { Bucket: params.Bucket, Region: params.Region, Url: paramsUrl });
  8525. var next = function (tryTimes) {
  8526. var oldClockOffset = self.options.SystemClockOffset;
  8527. getAuthorizationAsync.call(self, {
  8528. Bucket: params.Bucket || '',
  8529. Region: params.Region || '',
  8530. Method: params.method,
  8531. Key: params.Key,
  8532. Query: Query,
  8533. Headers: params.headers,
  8534. SignHost: SignHost,
  8535. Action: params.Action,
  8536. ResourceKey: params.ResourceKey,
  8537. Scope: params.Scope,
  8538. ForceSignHost: self.options.ForceSignHost
  8539. }, function (err, AuthData) {
  8540. if (err) {
  8541. callback(err);
  8542. return;
  8543. }
  8544. params.AuthData = AuthData;
  8545. _submitRequest.call(self, params, function (err, data) {
  8546. if (err && tryTimes < 2 && (oldClockOffset !== self.options.SystemClockOffset || allowRetry.call(self, err))) {
  8547. if (params.headers) {
  8548. delete params.headers.Authorization;
  8549. delete params.headers['token'];
  8550. delete params.headers['clientIP'];
  8551. delete params.headers['clientUA'];
  8552. params.headers['x-cos-security-token'] && delete params.headers['x-cos-security-token'];
  8553. params.headers['x-ci-security-token'] && delete params.headers['x-ci-security-token'];
  8554. }
  8555. next(tryTimes + 1);
  8556. } else {
  8557. callback(err, data);
  8558. }
  8559. });
  8560. });
  8561. };
  8562. next(1);
  8563. }
  8564. // 发起请求
  8565. function _submitRequest(params, callback) {
  8566. var self = this;
  8567. var TaskId = params.TaskId;
  8568. if (TaskId && !self._isRunningTask(TaskId)) return;
  8569. var bucket = params.Bucket;
  8570. var region = params.Region;
  8571. var object = params.Key;
  8572. var method = params.method || 'GET';
  8573. var url = params.Url || params.url;
  8574. var body = params.body;
  8575. var rawBody = params.rawBody;
  8576. // url
  8577. if (self.options.UseAccelerate) {
  8578. region = 'accelerate';
  8579. }
  8580. url = url || getUrl({
  8581. ForcePathStyle: self.options.ForcePathStyle,
  8582. protocol: self.options.Protocol,
  8583. domain: self.options.Domain,
  8584. bucket: bucket,
  8585. region: region,
  8586. object: object
  8587. });
  8588. if (params.action) {
  8589. url = url + '?' + params.action;
  8590. }
  8591. if (params.qsStr) {
  8592. if (url.indexOf('?') > -1) {
  8593. url = url + '&' + params.qsStr;
  8594. } else {
  8595. url = url + '?' + params.qsStr;
  8596. }
  8597. }
  8598. var opt = {
  8599. method: method,
  8600. url: url,
  8601. headers: params.headers,
  8602. qs: params.qs,
  8603. body: body
  8604. };
  8605. // 兼容ci接口
  8606. var token = 'x-cos-security-token';
  8607. if (util.isCIHost(url)) {
  8608. token = 'x-ci-security-token';
  8609. }
  8610. // 获取签名
  8611. opt.headers.Authorization = params.AuthData.Authorization;
  8612. params.AuthData.Token && (opt.headers['token'] = params.AuthData.Token);
  8613. params.AuthData.ClientIP && (opt.headers['clientIP'] = params.AuthData.ClientIP);
  8614. params.AuthData.ClientUA && (opt.headers['clientUA'] = params.AuthData.ClientUA);
  8615. params.AuthData.SecurityToken && (opt.headers[token] = params.AuthData.SecurityToken);
  8616. // 清理 undefined 和 null 字段
  8617. opt.headers && (opt.headers = util.clearKey(opt.headers));
  8618. opt = util.clearKey(opt);
  8619. // progress
  8620. if (params.onProgress && typeof params.onProgress === 'function') {
  8621. var contentLength = body && (body.size || body.length) || 0;
  8622. opt.onProgress = function (e) {
  8623. if (TaskId && !self._isRunningTask(TaskId)) return;
  8624. var loaded = e ? e.loaded : 0;
  8625. params.onProgress({ loaded: loaded, total: contentLength });
  8626. };
  8627. }
  8628. if (params.onDownloadProgress) {
  8629. opt.onDownloadProgress = params.onDownloadProgress;
  8630. }
  8631. if (params.DataType) {
  8632. opt.dataType = params.DataType;
  8633. }
  8634. if (this.options.Timeout) {
  8635. opt.timeout = this.options.Timeout;
  8636. }
  8637. self.options.ForcePathStyle && (opt.pathStyle = self.options.ForcePathStyle);
  8638. self.emit('before-send', opt);
  8639. var sender = (self.options.Request || REQUEST)(opt, function (r) {
  8640. if (r.error === 'abort') return;
  8641. var receive = {
  8642. options: opt,
  8643. error: err,
  8644. statusCode: response && response.statusCode || 0,
  8645. headers: response && response.headers || {},
  8646. body: body
  8647. };
  8648. self.emit('after-receive', receive);
  8649. err = receive.error;
  8650. body = receive.body;
  8651. response = {
  8652. statusCode: receive.statusCode,
  8653. headers: receive.headers
  8654. };
  8655. // 抛出事件,允许修改返回值的 error、statusCode、statusMessage、body
  8656. self.emit('after-receive', r);
  8657. var response = { statusCode: r.statusCode, statusMessage: r.statusMessage, headers: r.headers };
  8658. var err = r.error;
  8659. var body = r.body;
  8660. // 返回内容添加 状态码 和 headers
  8661. var hasReturned;
  8662. var cb = function (err, data) {
  8663. TaskId && self.off('inner-kill-task', killTask);
  8664. if (hasReturned) return;
  8665. hasReturned = true;
  8666. var attrs = {};
  8667. response && response.statusCode && (attrs.statusCode = response.statusCode);
  8668. response && response.headers && (attrs.headers = response.headers);
  8669. if (err) {
  8670. err = util.extend(err || {}, attrs);
  8671. callback(err, null);
  8672. } else {
  8673. data = util.extend(data || {}, attrs);
  8674. callback(null, data);
  8675. }
  8676. sender = null;
  8677. };
  8678. // 请求错误,发生网络错误
  8679. if (err) return cb(util.error(err));
  8680. // 请求返回码不为 200
  8681. var statusCode = response.statusCode;
  8682. var statusSuccess = Math.floor(statusCode / 100) === 2; // 200 202 204 206
  8683. // 不对 body 进行转换,body 直接挂载返回
  8684. if (rawBody && statusSuccess) return cb(null, { body: body });
  8685. // 解析 xml body
  8686. var json;
  8687. try {
  8688. json = body && body.indexOf('<') > -1 && body.indexOf('>') > -1 && util.xml2json(body) || {};
  8689. } catch (e) {
  8690. json = {};
  8691. }
  8692. // 处理返回值
  8693. var xmlError = json && json.Error;
  8694. if (statusSuccess) {
  8695. // 正确返回,状态码 2xx 时,body 不会有 Error
  8696. cb(null, json);
  8697. } else if (xmlError) {
  8698. // 正常返回了 xml body,且有 Error 节点
  8699. cb(util.error(new Error(xmlError.Message), { code: xmlError.Code, error: xmlError }));
  8700. } else if (statusCode) {
  8701. // 有错误的状态码
  8702. cb(util.error(new Error(response.statusMessage), { code: '' + statusCode }));
  8703. } else if (statusCode) {
  8704. // 无状态码,或者获取不到状态码
  8705. cb(util.error(new Error('statusCode error')));
  8706. }
  8707. });
  8708. // kill task
  8709. var killTask = function (data) {
  8710. if (data.TaskId === TaskId) {
  8711. sender && sender.abort && sender.abort();
  8712. self.off('inner-kill-task', killTask);
  8713. }
  8714. };
  8715. TaskId && self.on('inner-kill-task', killTask);
  8716. }
  8717. var API_MAP = {
  8718. // Bucket 相关方法
  8719. getService: getService, // Bucket
  8720. putBucket: putBucket,
  8721. headBucket: headBucket, // Bucket
  8722. getBucket: getBucket,
  8723. deleteBucket: deleteBucket,
  8724. putBucketAcl: putBucketAcl, // BucketACL
  8725. getBucketAcl: getBucketAcl,
  8726. putBucketCors: putBucketCors, // BucketCors
  8727. getBucketCors: getBucketCors,
  8728. deleteBucketCors: deleteBucketCors,
  8729. getBucketLocation: getBucketLocation, // BucketLocation
  8730. getBucketPolicy: getBucketPolicy, // BucketPolicy
  8731. putBucketPolicy: putBucketPolicy,
  8732. deleteBucketPolicy: deleteBucketPolicy,
  8733. putBucketTagging: putBucketTagging, // BucketTagging
  8734. getBucketTagging: getBucketTagging,
  8735. deleteBucketTagging: deleteBucketTagging,
  8736. putBucketLifecycle: putBucketLifecycle, // BucketLifecycle
  8737. getBucketLifecycle: getBucketLifecycle,
  8738. deleteBucketLifecycle: deleteBucketLifecycle,
  8739. putBucketVersioning: putBucketVersioning, // BucketVersioning
  8740. getBucketVersioning: getBucketVersioning,
  8741. putBucketReplication: putBucketReplication, // BucketReplication
  8742. getBucketReplication: getBucketReplication,
  8743. deleteBucketReplication: deleteBucketReplication,
  8744. putBucketWebsite: putBucketWebsite, // BucketWebsite
  8745. getBucketWebsite: getBucketWebsite,
  8746. deleteBucketWebsite: deleteBucketWebsite,
  8747. putBucketReferer: putBucketReferer, // BucketReferer
  8748. getBucketReferer: getBucketReferer,
  8749. putBucketDomain: putBucketDomain, // BucketDomain
  8750. getBucketDomain: getBucketDomain,
  8751. deleteBucketDomain: deleteBucketDomain,
  8752. putBucketOrigin: putBucketOrigin, // BucketOrigin
  8753. getBucketOrigin: getBucketOrigin,
  8754. deleteBucketOrigin: deleteBucketOrigin,
  8755. putBucketLogging: putBucketLogging, // BucketLogging
  8756. getBucketLogging: getBucketLogging,
  8757. putBucketInventory: putBucketInventory, // BucketInventory
  8758. getBucketInventory: getBucketInventory,
  8759. listBucketInventory: listBucketInventory,
  8760. deleteBucketInventory: deleteBucketInventory,
  8761. putBucketAccelerate: putBucketAccelerate,
  8762. getBucketAccelerate: getBucketAccelerate,
  8763. putBucketEncryption: putBucketEncryption,
  8764. getBucketEncryption: getBucketEncryption,
  8765. deleteBucketEncryption: deleteBucketEncryption,
  8766. // Object 相关方法
  8767. getObject: getObject,
  8768. headObject: headObject,
  8769. listObjectVersions: listObjectVersions,
  8770. putObject: putObject,
  8771. deleteObject: deleteObject,
  8772. getObjectAcl: getObjectAcl,
  8773. putObjectAcl: putObjectAcl,
  8774. optionsObject: optionsObject,
  8775. putObjectCopy: putObjectCopy,
  8776. deleteMultipleObject: deleteMultipleObject,
  8777. restoreObject: restoreObject,
  8778. putObjectTagging: putObjectTagging,
  8779. getObjectTagging: getObjectTagging,
  8780. deleteObjectTagging: deleteObjectTagging,
  8781. selectObjectContent: selectObjectContent,
  8782. appendObject: appendObject,
  8783. // 分块上传相关方法
  8784. uploadPartCopy: uploadPartCopy,
  8785. multipartInit: multipartInit,
  8786. multipartUpload: multipartUpload,
  8787. multipartComplete: multipartComplete,
  8788. multipartList: multipartList,
  8789. multipartListPart: multipartListPart,
  8790. multipartAbort: multipartAbort,
  8791. // 工具方法
  8792. request: request,
  8793. getObjectUrl: getObjectUrl,
  8794. getAuth: getAuth
  8795. };
  8796. function warnOldApi(apiName, fn, proto) {
  8797. util.each(['Cors', 'Acl'], function (suffix) {
  8798. if (apiName.slice(-suffix.length) === suffix) {
  8799. var oldName = apiName.slice(0, -suffix.length) + suffix.toUpperCase();
  8800. var apiFn = util.apiWrapper(apiName, fn);
  8801. var warned = false;
  8802. proto[oldName] = function () {
  8803. !warned && console.warn('warning: cos.' + oldName + ' has been deprecated. Please Use cos.' + apiName + ' instead.');
  8804. warned = true;
  8805. apiFn.apply(this, arguments);
  8806. };
  8807. }
  8808. });
  8809. }
  8810. module.exports.init = function (COS, task) {
  8811. task.transferToTaskMethod(API_MAP, 'putObject');
  8812. util.each(API_MAP, function (fn, apiName) {
  8813. COS.prototype[apiName] = util.apiWrapper(apiName, fn);
  8814. warnOldApi(apiName, fn, COS.prototype);
  8815. });
  8816. };
  8817. /***/ }),
  8818. /* 20 */
  8819. /***/ (function(module, exports) {
  8820. var stringifyPrimitive = function (v) {
  8821. switch (typeof v) {
  8822. case 'string':
  8823. return v;
  8824. case 'boolean':
  8825. return v ? 'true' : 'false';
  8826. case 'number':
  8827. return isFinite(v) ? v : '';
  8828. default:
  8829. return '';
  8830. }
  8831. };
  8832. var queryStringify = function (obj, sep, eq, name) {
  8833. sep = sep || '&';
  8834. eq = eq || '=';
  8835. if (obj === null) {
  8836. obj = undefined;
  8837. }
  8838. if (typeof obj === 'object') {
  8839. return Object.keys(obj).map(function (k) {
  8840. var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
  8841. if (Array.isArray(obj[k])) {
  8842. return obj[k].map(function (v) {
  8843. return ks + encodeURIComponent(stringifyPrimitive(v));
  8844. }).join(sep);
  8845. } else {
  8846. return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
  8847. }
  8848. }).filter(Boolean).join(sep);
  8849. }
  8850. if (!name) return '';
  8851. return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj));
  8852. };
  8853. var xhrRes = function (err, xhr, body) {
  8854. var headers = {};
  8855. xhr.getAllResponseHeaders().trim().split('\n').forEach(function (item) {
  8856. if (item) {
  8857. var index = item.indexOf(':');
  8858. var key = item.substr(0, index).trim().toLowerCase();
  8859. var val = item.substr(index + 1).trim();
  8860. headers[key] = val;
  8861. }
  8862. });
  8863. return {
  8864. error: err,
  8865. statusCode: xhr.status,
  8866. statusMessage: xhr.statusText,
  8867. headers: headers,
  8868. body: body
  8869. };
  8870. };
  8871. var xhrBody = function (xhr, dataType) {
  8872. return !dataType && dataType === 'text' ? xhr.responseText : xhr.response;
  8873. };
  8874. var request = function (opt, callback) {
  8875. // method
  8876. var method = (opt.method || 'GET').toUpperCase();
  8877. // url、qs
  8878. var url = opt.url;
  8879. if (opt.qs) {
  8880. var qsStr = queryStringify(opt.qs);
  8881. if (qsStr) {
  8882. url += (url.indexOf('?') === -1 ? '?' : '&') + qsStr;
  8883. }
  8884. }
  8885. // 创建 ajax 实例
  8886. var xhr = new XMLHttpRequest();
  8887. xhr.open(method, url, true);
  8888. xhr.responseType = opt.dataType || 'text';
  8889. // 处理 xhrFields 属性
  8890. if (opt.xhrFields) {
  8891. for (var xhrField in opt.xhrFields) {
  8892. xhr[xhrField] = opt.xhrFields[xhrField];
  8893. }
  8894. }
  8895. // 处理 headers
  8896. var headers = opt.headers;
  8897. if (headers) {
  8898. for (var key in headers) {
  8899. if (headers.hasOwnProperty(key) && key.toLowerCase() !== 'content-length' && key.toLowerCase() !== 'user-agent' && key.toLowerCase() !== 'origin' && key.toLowerCase() !== 'host') {
  8900. xhr.setRequestHeader(key, headers[key]);
  8901. }
  8902. }
  8903. }
  8904. // onprogress
  8905. if (opt.onProgress && xhr.upload) xhr.upload.onprogress = opt.onProgress;
  8906. if (opt.onDownloadProgress) xhr.onprogress = opt.onDownloadProgress;
  8907. // timeout
  8908. if (opt.timeout) xhr.timeout = opt.timeout;
  8909. xhr.ontimeout = function (event) {
  8910. var error = new Error('timeout');
  8911. callback(xhrRes(error, xhr));
  8912. };
  8913. // success 2xx/3xx/4xx
  8914. xhr.onload = function () {
  8915. callback(xhrRes(null, xhr, xhrBody(xhr, opt.dataType)));
  8916. };
  8917. // error 5xx/0 (网络错误、跨域报错、Https connect-src 限制的报错时 statusCode 为 0)
  8918. xhr.onerror = function (err) {
  8919. var body = xhrBody(xhr, opt.dataType);
  8920. if (body) {
  8921. // 5xx
  8922. callback(xhrRes(null, xhr, body));
  8923. } else {
  8924. // 0
  8925. var error = xhr.statusText;
  8926. if (!error && xhr.status === 0) error = new Error('CORS blocked or network error');
  8927. callback(xhrRes(error, xhr, body));
  8928. }
  8929. };
  8930. // send
  8931. xhr.send(opt.body || '');
  8932. // 返回 ajax 实例,用于外部调用 xhr.abort
  8933. return xhr;
  8934. };
  8935. module.exports = request;
  8936. /***/ }),
  8937. /* 21 */
  8938. /***/ (function(module, exports, __webpack_require__) {
  8939. var session = __webpack_require__(5);
  8940. var Async = __webpack_require__(22);
  8941. var EventProxy = __webpack_require__(4).EventProxy;
  8942. var util = __webpack_require__(0);
  8943. // 文件分块上传全过程,暴露的分块上传接口
  8944. function sliceUploadFile(params, callback) {
  8945. var self = this;
  8946. var ep = new EventProxy();
  8947. var TaskId = params.TaskId;
  8948. var Bucket = params.Bucket;
  8949. var Region = params.Region;
  8950. var Key = params.Key;
  8951. var Body = params.Body;
  8952. var ChunkSize = params.ChunkSize || params.SliceSize || self.options.ChunkSize;
  8953. var AsyncLimit = params.AsyncLimit;
  8954. var StorageClass = params.StorageClass;
  8955. var ServerSideEncryption = params.ServerSideEncryption;
  8956. var FileSize;
  8957. var onProgress;
  8958. var onHashProgress = params.onHashProgress;
  8959. // 上传过程中出现错误,返回错误
  8960. ep.on('error', function (err) {
  8961. if (!self._isRunningTask(TaskId)) return;
  8962. err.UploadId = params.UploadData.UploadId || '';
  8963. return callback(err);
  8964. });
  8965. // 上传分块完成,开始 uploadSliceComplete 操作
  8966. ep.on('upload_complete', function (UploadCompleteData) {
  8967. var _UploadCompleteData = util.extend({
  8968. UploadId: params.UploadData.UploadId || ''
  8969. }, UploadCompleteData);
  8970. callback(null, _UploadCompleteData);
  8971. });
  8972. // 上传分块完成,开始 uploadSliceComplete 操作
  8973. ep.on('upload_slice_complete', function (UploadData) {
  8974. var metaHeaders = {};
  8975. util.each(params.Headers, function (val, k) {
  8976. var shortKey = k.toLowerCase();
  8977. if (shortKey.indexOf('x-cos-meta-') === 0 || shortKey === 'pic-operations') metaHeaders[k] = val;
  8978. });
  8979. uploadSliceComplete.call(self, {
  8980. Bucket: Bucket,
  8981. Region: Region,
  8982. Key: Key,
  8983. UploadId: UploadData.UploadId,
  8984. SliceList: UploadData.SliceList,
  8985. Headers: metaHeaders
  8986. }, function (err, data) {
  8987. if (!self._isRunningTask(TaskId)) return;
  8988. session.removeUsing(UploadData.UploadId);
  8989. if (err) {
  8990. onProgress(null, true);
  8991. return ep.emit('error', err);
  8992. }
  8993. session.removeUploadId.call(self, UploadData.UploadId);
  8994. onProgress({ loaded: FileSize, total: FileSize }, true);
  8995. ep.emit('upload_complete', data);
  8996. });
  8997. });
  8998. // 获取 UploadId 完成,开始上传每个分片
  8999. ep.on('get_upload_data_finish', function (UploadData) {
  9000. // 处理 UploadId 缓存
  9001. var uuid = session.getFileId(Body, params.ChunkSize, Bucket, Key);
  9002. uuid && session.saveUploadId.call(self, uuid, UploadData.UploadId, self.options.UploadIdCacheLimit); // 缓存 UploadId
  9003. session.setUsing(UploadData.UploadId); // 标记 UploadId 为正在使用
  9004. // 获取 UploadId
  9005. onProgress(null, true); // 任务状态开始 uploading
  9006. uploadSliceList.call(self, {
  9007. TaskId: TaskId,
  9008. Bucket: Bucket,
  9009. Region: Region,
  9010. Key: Key,
  9011. Body: Body,
  9012. FileSize: FileSize,
  9013. SliceSize: ChunkSize,
  9014. AsyncLimit: AsyncLimit,
  9015. ServerSideEncryption: ServerSideEncryption,
  9016. UploadData: UploadData,
  9017. Headers: params.Headers,
  9018. onProgress: onProgress
  9019. }, function (err, data) {
  9020. if (!self._isRunningTask(TaskId)) return;
  9021. if (err) {
  9022. onProgress(null, true);
  9023. return ep.emit('error', err);
  9024. }
  9025. ep.emit('upload_slice_complete', data);
  9026. });
  9027. });
  9028. // 开始获取文件 UploadId,里面会视情况计算 ETag,并比对,保证文件一致性,也优化上传
  9029. ep.on('get_file_size_finish', function () {
  9030. onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
  9031. if (params.UploadData.UploadId) {
  9032. ep.emit('get_upload_data_finish', params.UploadData);
  9033. } else {
  9034. var _params = util.extend({
  9035. TaskId: TaskId,
  9036. Bucket: Bucket,
  9037. Region: Region,
  9038. Key: Key,
  9039. Headers: params.Headers,
  9040. StorageClass: StorageClass,
  9041. Body: Body,
  9042. FileSize: FileSize,
  9043. SliceSize: ChunkSize,
  9044. onHashProgress: onHashProgress
  9045. }, params);
  9046. getUploadIdAndPartList.call(self, _params, function (err, UploadData) {
  9047. if (!self._isRunningTask(TaskId)) return;
  9048. if (err) return ep.emit('error', err);
  9049. params.UploadData.UploadId = UploadData.UploadId;
  9050. params.UploadData.PartList = UploadData.PartList;
  9051. ep.emit('get_upload_data_finish', params.UploadData);
  9052. });
  9053. }
  9054. });
  9055. // 获取上传文件大小
  9056. FileSize = params.ContentLength;
  9057. delete params.ContentLength;
  9058. !params.Headers && (params.Headers = {});
  9059. util.each(params.Headers, function (item, key) {
  9060. if (key.toLowerCase() === 'content-length') {
  9061. delete params.Headers[key];
  9062. }
  9063. });
  9064. // 控制分片大小
  9065. (function () {
  9066. var SIZE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024 * 2, 1024 * 4, 1024 * 5];
  9067. var AutoChunkSize = 1024 * 1024;
  9068. for (var i = 0; i < SIZE.length; i++) {
  9069. AutoChunkSize = SIZE[i] * 1024 * 1024;
  9070. if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
  9071. }
  9072. params.ChunkSize = params.SliceSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
  9073. })();
  9074. // 开始上传
  9075. if (FileSize === 0) {
  9076. params.Body = '';
  9077. params.ContentLength = 0;
  9078. params.SkipTask = true;
  9079. self.putObject(params, callback);
  9080. } else {
  9081. ep.emit('get_file_size_finish');
  9082. }
  9083. }
  9084. // 获取上传任务的 UploadId
  9085. function getUploadIdAndPartList(params, callback) {
  9086. var TaskId = params.TaskId;
  9087. var Bucket = params.Bucket;
  9088. var Region = params.Region;
  9089. var Key = params.Key;
  9090. var StorageClass = params.StorageClass;
  9091. var self = this;
  9092. // 计算 ETag
  9093. var ETagMap = {};
  9094. var FileSize = params.FileSize;
  9095. var SliceSize = params.SliceSize;
  9096. var SliceCount = Math.ceil(FileSize / SliceSize);
  9097. var FinishSliceCount = 0;
  9098. var FinishSize = 0;
  9099. var onHashProgress = util.throttleOnProgress.call(self, FileSize, params.onHashProgress);
  9100. var getChunkETag = function (PartNumber, callback) {
  9101. var start = SliceSize * (PartNumber - 1);
  9102. var end = Math.min(start + SliceSize, FileSize);
  9103. var ChunkSize = end - start;
  9104. if (ETagMap[PartNumber]) {
  9105. callback(null, {
  9106. PartNumber: PartNumber,
  9107. ETag: ETagMap[PartNumber],
  9108. Size: ChunkSize
  9109. });
  9110. } else {
  9111. util.fileSlice(params.Body, start, end, false, function (chunkItem) {
  9112. util.getFileMd5(chunkItem, function (err, md5) {
  9113. if (err) return callback(util.error(err));
  9114. var ETag = '"' + md5 + '"';
  9115. ETagMap[PartNumber] = ETag;
  9116. FinishSliceCount += 1;
  9117. FinishSize += ChunkSize;
  9118. onHashProgress({ loaded: FinishSize, total: FileSize });
  9119. callback(null, {
  9120. PartNumber: PartNumber,
  9121. ETag: ETag,
  9122. Size: ChunkSize
  9123. });
  9124. });
  9125. });
  9126. }
  9127. };
  9128. // 通过和文件的 md5 对比,判断 UploadId 是否可用
  9129. var isAvailableUploadList = function (PartList, callback) {
  9130. var PartCount = PartList.length;
  9131. // 如果没有分片,通过
  9132. if (PartCount === 0) {
  9133. return callback(null, true);
  9134. }
  9135. // 检查分片数量
  9136. if (PartCount > SliceCount) {
  9137. return callback(null, false);
  9138. }
  9139. // 检查分片大小
  9140. if (PartCount > 1) {
  9141. var PartSliceSize = Math.max(PartList[0].Size, PartList[1].Size);
  9142. if (PartSliceSize !== SliceSize) {
  9143. return callback(null, false);
  9144. }
  9145. }
  9146. // 逐个分片计算并检查 ETag 是否一致
  9147. var next = function (index) {
  9148. if (index < PartCount) {
  9149. var Part = PartList[index];
  9150. getChunkETag(Part.PartNumber, function (err, chunk) {
  9151. if (chunk && chunk.ETag === Part.ETag && chunk.Size === Part.Size) {
  9152. next(index + 1);
  9153. } else {
  9154. callback(null, false);
  9155. }
  9156. });
  9157. } else {
  9158. callback(null, true);
  9159. }
  9160. };
  9161. next(0);
  9162. };
  9163. var ep = new EventProxy();
  9164. ep.on('error', function (errData) {
  9165. if (!self._isRunningTask(TaskId)) return;
  9166. return callback(errData);
  9167. });
  9168. // 存在 UploadId
  9169. ep.on('upload_id_available', function (UploadData) {
  9170. // 转换成 map
  9171. var map = {};
  9172. var list = [];
  9173. util.each(UploadData.PartList, function (item) {
  9174. map[item.PartNumber] = item;
  9175. });
  9176. for (var PartNumber = 1; PartNumber <= SliceCount; PartNumber++) {
  9177. var item = map[PartNumber];
  9178. if (item) {
  9179. item.PartNumber = PartNumber;
  9180. item.Uploaded = true;
  9181. } else {
  9182. item = {
  9183. PartNumber: PartNumber,
  9184. ETag: null,
  9185. Uploaded: false
  9186. };
  9187. }
  9188. list.push(item);
  9189. }
  9190. UploadData.PartList = list;
  9191. callback(null, UploadData);
  9192. });
  9193. // 不存在 UploadId, 初始化生成 UploadId
  9194. ep.on('no_available_upload_id', function () {
  9195. if (!self._isRunningTask(TaskId)) return;
  9196. var _params = util.extend({
  9197. Bucket: Bucket,
  9198. Region: Region,
  9199. Key: Key,
  9200. Query: util.clone(params.Query),
  9201. StorageClass: StorageClass,
  9202. Body: params.Body
  9203. }, params);
  9204. var headers = util.clone(params.Headers);
  9205. delete headers['x-cos-mime-limit'];
  9206. _params.Headers = headers;
  9207. self.multipartInit(_params, function (err, data) {
  9208. if (!self._isRunningTask(TaskId)) return;
  9209. if (err) return ep.emit('error', err);
  9210. var UploadId = data.UploadId;
  9211. if (!UploadId) {
  9212. return callback(util.error(new Error('no such upload id')));
  9213. }
  9214. ep.emit('upload_id_available', { UploadId: UploadId, PartList: [] });
  9215. });
  9216. });
  9217. // 如果已存在 UploadId,找一个可以用的 UploadId
  9218. ep.on('has_and_check_upload_id', function (UploadIdList) {
  9219. // 串行地,找一个内容一致的 UploadId
  9220. UploadIdList = UploadIdList.reverse();
  9221. Async.eachLimit(UploadIdList, 1, function (UploadId, asyncCallback) {
  9222. if (!self._isRunningTask(TaskId)) return;
  9223. // 如果正在上传,跳过
  9224. if (session.using[UploadId]) {
  9225. asyncCallback(); // 检查下一个 UploadId
  9226. return;
  9227. }
  9228. // 判断 UploadId 是否可用
  9229. wholeMultipartListPart.call(self, {
  9230. Bucket: Bucket,
  9231. Region: Region,
  9232. Key: Key,
  9233. UploadId: UploadId
  9234. }, function (err, PartListData) {
  9235. if (!self._isRunningTask(TaskId)) return;
  9236. if (err) {
  9237. session.removeUsing(UploadId);
  9238. return ep.emit('error', err);
  9239. }
  9240. var PartList = PartListData.PartList;
  9241. PartList.forEach(function (item) {
  9242. item.PartNumber *= 1;
  9243. item.Size *= 1;
  9244. item.ETag = item.ETag || '';
  9245. });
  9246. isAvailableUploadList(PartList, function (err, isAvailable) {
  9247. if (!self._isRunningTask(TaskId)) return;
  9248. if (err) return ep.emit('error', err);
  9249. if (isAvailable) {
  9250. asyncCallback({
  9251. UploadId: UploadId,
  9252. PartList: PartList
  9253. }); // 马上结束
  9254. } else {
  9255. asyncCallback(); // 检查下一个 UploadId
  9256. }
  9257. });
  9258. });
  9259. }, function (AvailableUploadData) {
  9260. if (!self._isRunningTask(TaskId)) return;
  9261. onHashProgress(null, true);
  9262. if (AvailableUploadData && AvailableUploadData.UploadId) {
  9263. ep.emit('upload_id_available', AvailableUploadData);
  9264. } else {
  9265. ep.emit('no_available_upload_id');
  9266. }
  9267. });
  9268. });
  9269. // 在本地缓存找可用的 UploadId
  9270. ep.on('seek_local_avail_upload_id', function (RemoteUploadIdList) {
  9271. // 在本地找可用的 UploadId
  9272. var uuid = session.getFileId(params.Body, params.ChunkSize, Bucket, Key);
  9273. var LocalUploadIdList = session.getUploadIdList.call(self, uuid);
  9274. if (!uuid || !LocalUploadIdList) {
  9275. ep.emit('has_and_check_upload_id', RemoteUploadIdList);
  9276. return;
  9277. }
  9278. var next = function (index) {
  9279. // 如果本地找不到可用 UploadId,再一个个遍历校验远端
  9280. if (index >= LocalUploadIdList.length) {
  9281. ep.emit('has_and_check_upload_id', RemoteUploadIdList);
  9282. return;
  9283. }
  9284. var UploadId = LocalUploadIdList[index];
  9285. // 如果不在远端 UploadId 列表里,跳过并删除
  9286. if (!util.isInArray(RemoteUploadIdList, UploadId)) {
  9287. session.removeUploadId.call(self, UploadId);
  9288. next(index + 1);
  9289. return;
  9290. }
  9291. // 如果正在上传,跳过
  9292. if (session.using[UploadId]) {
  9293. next(index + 1);
  9294. return;
  9295. }
  9296. // 判断 UploadId 是否存在线上
  9297. wholeMultipartListPart.call(self, {
  9298. Bucket: Bucket,
  9299. Region: Region,
  9300. Key: Key,
  9301. UploadId: UploadId
  9302. }, function (err, PartListData) {
  9303. if (!self._isRunningTask(TaskId)) return;
  9304. if (err) {
  9305. // 如果 UploadId 获取会出错,跳过并删除
  9306. session.removeUploadId.call(self, UploadId);
  9307. next(index + 1);
  9308. } else {
  9309. // 找到可用 UploadId
  9310. ep.emit('upload_id_available', {
  9311. UploadId: UploadId,
  9312. PartList: PartListData.PartList
  9313. });
  9314. }
  9315. });
  9316. };
  9317. next(0);
  9318. });
  9319. // 获取线上 UploadId 列表
  9320. ep.on('get_remote_upload_id_list', function () {
  9321. // 获取符合条件的 UploadId 列表,因为同一个文件可以有多个上传任务。
  9322. wholeMultipartList.call(self, {
  9323. Bucket: Bucket,
  9324. Region: Region,
  9325. Key: Key
  9326. }, function (err, data) {
  9327. if (!self._isRunningTask(TaskId)) return;
  9328. if (err) return ep.emit('error', err);
  9329. // 整理远端 UploadId 列表
  9330. var RemoteUploadIdList = util.filter(data.UploadList, function (item) {
  9331. return item.Key === Key && (!StorageClass || item.StorageClass.toUpperCase() === StorageClass.toUpperCase());
  9332. }).reverse().map(function (item) {
  9333. return item.UploadId || item.UploadID;
  9334. });
  9335. if (RemoteUploadIdList.length) {
  9336. ep.emit('seek_local_avail_upload_id', RemoteUploadIdList);
  9337. } else {
  9338. // 远端没有 UploadId,清理缓存的 UploadId
  9339. var uuid = session.getFileId(params.Body, params.ChunkSize, Bucket, Key),
  9340. LocalUploadIdList;
  9341. if (uuid && (LocalUploadIdList = session.getUploadIdList.call(self, uuid))) {
  9342. util.each(LocalUploadIdList, function (UploadId) {
  9343. session.removeUploadId.call(self, UploadId);
  9344. });
  9345. }
  9346. ep.emit('no_available_upload_id');
  9347. }
  9348. });
  9349. });
  9350. // 开始找可用 UploadId
  9351. ep.emit('get_remote_upload_id_list');
  9352. }
  9353. // 获取符合条件的全部上传任务 (条件包括 Bucket, Region, Prefix)
  9354. function wholeMultipartList(params, callback) {
  9355. var self = this;
  9356. var UploadList = [];
  9357. var sendParams = {
  9358. Bucket: params.Bucket,
  9359. Region: params.Region,
  9360. Prefix: params.Key
  9361. };
  9362. var next = function () {
  9363. self.multipartList(sendParams, function (err, data) {
  9364. if (err) return callback(err);
  9365. UploadList.push.apply(UploadList, data.Upload || []);
  9366. if (data.IsTruncated === 'true') {
  9367. // 列表不完整
  9368. sendParams.KeyMarker = data.NextKeyMarker;
  9369. sendParams.UploadIdMarker = data.NextUploadIdMarker;
  9370. next();
  9371. } else {
  9372. callback(null, { UploadList: UploadList });
  9373. }
  9374. });
  9375. };
  9376. next();
  9377. }
  9378. // 获取指定上传任务的分块列表
  9379. function wholeMultipartListPart(params, callback) {
  9380. var self = this;
  9381. var PartList = [];
  9382. var sendParams = {
  9383. Bucket: params.Bucket,
  9384. Region: params.Region,
  9385. Key: params.Key,
  9386. UploadId: params.UploadId
  9387. };
  9388. var next = function () {
  9389. self.multipartListPart(sendParams, function (err, data) {
  9390. if (err) return callback(err);
  9391. PartList.push.apply(PartList, data.Part || []);
  9392. if (data.IsTruncated === 'true') {
  9393. // 列表不完整
  9394. sendParams.PartNumberMarker = data.NextPartNumberMarker;
  9395. next();
  9396. } else {
  9397. callback(null, { PartList: PartList });
  9398. }
  9399. });
  9400. };
  9401. next();
  9402. }
  9403. // 上传文件分块,包括
  9404. /*
  9405. UploadId (上传任务编号)
  9406. AsyncLimit (并发量),
  9407. SliceList (上传的分块数组),
  9408. FilePath (本地文件的位置),
  9409. SliceSize (文件分块大小)
  9410. FileSize (文件大小)
  9411. onProgress (上传成功之后的回调函数)
  9412. */
  9413. function uploadSliceList(params, cb) {
  9414. var self = this;
  9415. var TaskId = params.TaskId;
  9416. var Bucket = params.Bucket;
  9417. var Region = params.Region;
  9418. var Key = params.Key;
  9419. var UploadData = params.UploadData;
  9420. var FileSize = params.FileSize;
  9421. var SliceSize = params.SliceSize;
  9422. var ChunkParallel = Math.min(params.AsyncLimit || self.options.ChunkParallelLimit || 1, 256);
  9423. var Body = params.Body;
  9424. var SliceCount = Math.ceil(FileSize / SliceSize);
  9425. var FinishSize = 0;
  9426. var ServerSideEncryption = params.ServerSideEncryption;
  9427. var Headers = params.Headers;
  9428. var needUploadSlices = util.filter(UploadData.PartList, function (SliceItem) {
  9429. if (SliceItem['Uploaded']) {
  9430. FinishSize += SliceItem['PartNumber'] >= SliceCount ? FileSize % SliceSize || SliceSize : SliceSize;
  9431. }
  9432. return !SliceItem['Uploaded'];
  9433. });
  9434. var onProgress = params.onProgress;
  9435. Async.eachLimit(needUploadSlices, ChunkParallel, function (SliceItem, asyncCallback) {
  9436. if (!self._isRunningTask(TaskId)) return;
  9437. var PartNumber = SliceItem['PartNumber'];
  9438. var currentSize = Math.min(FileSize, SliceItem['PartNumber'] * SliceSize) - (SliceItem['PartNumber'] - 1) * SliceSize;
  9439. var preAddSize = 0;
  9440. uploadSliceItem.call(self, {
  9441. TaskId: TaskId,
  9442. Bucket: Bucket,
  9443. Region: Region,
  9444. Key: Key,
  9445. SliceSize: SliceSize,
  9446. FileSize: FileSize,
  9447. PartNumber: PartNumber,
  9448. ServerSideEncryption: ServerSideEncryption,
  9449. Body: Body,
  9450. UploadData: UploadData,
  9451. Headers: Headers,
  9452. onProgress: function (data) {
  9453. FinishSize += data.loaded - preAddSize;
  9454. preAddSize = data.loaded;
  9455. onProgress({ loaded: FinishSize, total: FileSize });
  9456. }
  9457. }, function (err, data) {
  9458. if (!self._isRunningTask(TaskId)) return;
  9459. if (!err && !data.ETag) err = 'get ETag error, please add "ETag" to CORS ExposeHeader setting.( 获取ETag失败,请在CORS ExposeHeader设置中添加ETag,请参考文档:https://cloud.tencent.com/document/product/436/13318 )';
  9460. if (err) {
  9461. FinishSize -= preAddSize;
  9462. } else {
  9463. FinishSize += currentSize - preAddSize;
  9464. SliceItem.ETag = data.ETag;
  9465. }
  9466. onProgress({ loaded: FinishSize, total: FileSize });
  9467. asyncCallback(err || null, data);
  9468. });
  9469. }, function (err) {
  9470. if (!self._isRunningTask(TaskId)) return;
  9471. if (err) return cb(err);
  9472. cb(null, {
  9473. UploadId: UploadData.UploadId,
  9474. SliceList: UploadData.PartList
  9475. });
  9476. });
  9477. }
  9478. // 上传指定分片
  9479. function uploadSliceItem(params, callback) {
  9480. var self = this;
  9481. var TaskId = params.TaskId;
  9482. var Bucket = params.Bucket;
  9483. var Region = params.Region;
  9484. var Key = params.Key;
  9485. var FileSize = params.FileSize;
  9486. var FileBody = params.Body;
  9487. var PartNumber = params.PartNumber * 1;
  9488. var SliceSize = params.SliceSize;
  9489. var ServerSideEncryption = params.ServerSideEncryption;
  9490. var UploadData = params.UploadData;
  9491. var Headers = params.Headers || {};
  9492. var ChunkRetryTimes = self.options.ChunkRetryTimes + 1;
  9493. var start = SliceSize * (PartNumber - 1);
  9494. var ContentLength = SliceSize;
  9495. var end = start + SliceSize;
  9496. if (end > FileSize) {
  9497. end = FileSize;
  9498. ContentLength = end - start;
  9499. }
  9500. var headersWhiteList = ['x-cos-traffic-limit', 'x-cos-mime-limit'];
  9501. var headers = {};
  9502. util.each(Headers, function (v, k) {
  9503. if (headersWhiteList.indexOf(k) > -1) {
  9504. headers[k] = v;
  9505. }
  9506. });
  9507. var PartItem = UploadData.PartList[PartNumber - 1];
  9508. Async.retry(ChunkRetryTimes, function (tryCallback) {
  9509. if (!self._isRunningTask(TaskId)) return;
  9510. util.fileSlice(FileBody, start, end, true, function (Body) {
  9511. self.multipartUpload({
  9512. TaskId: TaskId,
  9513. Bucket: Bucket,
  9514. Region: Region,
  9515. Key: Key,
  9516. ContentLength: ContentLength,
  9517. PartNumber: PartNumber,
  9518. UploadId: UploadData.UploadId,
  9519. ServerSideEncryption: ServerSideEncryption,
  9520. Body: Body,
  9521. Headers: headers,
  9522. onProgress: params.onProgress
  9523. }, function (err, data) {
  9524. if (!self._isRunningTask(TaskId)) return;
  9525. if (err) return tryCallback(err);
  9526. PartItem.Uploaded = true;
  9527. return tryCallback(null, data);
  9528. });
  9529. });
  9530. }, function (err, data) {
  9531. if (!self._isRunningTask(TaskId)) return;
  9532. return callback(err, data);
  9533. });
  9534. }
  9535. // 完成分块上传
  9536. function uploadSliceComplete(params, callback) {
  9537. var Bucket = params.Bucket;
  9538. var Region = params.Region;
  9539. var Key = params.Key;
  9540. var UploadId = params.UploadId;
  9541. var SliceList = params.SliceList;
  9542. var self = this;
  9543. var ChunkRetryTimes = this.options.ChunkRetryTimes + 1;
  9544. var Headers = params.Headers;
  9545. var Parts = SliceList.map(function (item) {
  9546. return {
  9547. PartNumber: item.PartNumber,
  9548. ETag: item.ETag
  9549. };
  9550. });
  9551. // 完成上传的请求也做重试
  9552. Async.retry(ChunkRetryTimes, function (tryCallback) {
  9553. self.multipartComplete({
  9554. Bucket: Bucket,
  9555. Region: Region,
  9556. Key: Key,
  9557. UploadId: UploadId,
  9558. Parts: Parts,
  9559. Headers: Headers
  9560. }, tryCallback);
  9561. }, function (err, data) {
  9562. callback(err, data);
  9563. });
  9564. }
  9565. // 抛弃分块上传任务
  9566. /*
  9567. AsyncLimit (抛弃上传任务的并发量),
  9568. UploadId (上传任务的编号,当 Level 为 task 时候需要)
  9569. Level (抛弃分块上传任务的级别,task : 抛弃指定的上传任务,file : 抛弃指定的文件对应的上传任务,其他值 :抛弃指定Bucket 的全部上传任务)
  9570. */
  9571. function abortUploadTask(params, callback) {
  9572. var Bucket = params.Bucket;
  9573. var Region = params.Region;
  9574. var Key = params.Key;
  9575. var UploadId = params.UploadId;
  9576. var Level = params.Level || 'task';
  9577. var AsyncLimit = params.AsyncLimit;
  9578. var self = this;
  9579. var ep = new EventProxy();
  9580. ep.on('error', function (errData) {
  9581. return callback(errData);
  9582. });
  9583. // 已经获取到需要抛弃的任务列表
  9584. ep.on('get_abort_array', function (AbortArray) {
  9585. abortUploadTaskArray.call(self, {
  9586. Bucket: Bucket,
  9587. Region: Region,
  9588. Key: Key,
  9589. Headers: params.Headers,
  9590. AsyncLimit: AsyncLimit,
  9591. AbortArray: AbortArray
  9592. }, callback);
  9593. });
  9594. if (Level === 'bucket') {
  9595. // Bucket 级别的任务抛弃,抛弃该 Bucket 下的全部上传任务
  9596. wholeMultipartList.call(self, {
  9597. Bucket: Bucket,
  9598. Region: Region
  9599. }, function (err, data) {
  9600. if (err) return callback(err);
  9601. ep.emit('get_abort_array', data.UploadList || []);
  9602. });
  9603. } else if (Level === 'file') {
  9604. // 文件级别的任务抛弃,抛弃该文件的全部上传任务
  9605. if (!Key) return callback(util.error(new Error('abort_upload_task_no_key')));
  9606. wholeMultipartList.call(self, {
  9607. Bucket: Bucket,
  9608. Region: Region,
  9609. Key: Key
  9610. }, function (err, data) {
  9611. if (err) return callback(err);
  9612. ep.emit('get_abort_array', data.UploadList || []);
  9613. });
  9614. } else if (Level === 'task') {
  9615. // 单个任务级别的任务抛弃,抛弃指定 UploadId 的上传任务
  9616. if (!UploadId) return callback(util.error(new Error('abort_upload_task_no_id')));
  9617. if (!Key) return callback(util.error(new Error('abort_upload_task_no_key')));
  9618. ep.emit('get_abort_array', [{
  9619. Key: Key,
  9620. UploadId: UploadId
  9621. }]);
  9622. } else {
  9623. return callback(util.error(new Error('abort_unknown_level')));
  9624. }
  9625. }
  9626. // 批量抛弃分块上传任务
  9627. function abortUploadTaskArray(params, callback) {
  9628. var Bucket = params.Bucket;
  9629. var Region = params.Region;
  9630. var Key = params.Key;
  9631. var AbortArray = params.AbortArray;
  9632. var AsyncLimit = params.AsyncLimit || 1;
  9633. var self = this;
  9634. var index = 0;
  9635. var resultList = new Array(AbortArray.length);
  9636. Async.eachLimit(AbortArray, AsyncLimit, function (AbortItem, nextItem) {
  9637. var eachIndex = index;
  9638. if (Key && Key !== AbortItem.Key) {
  9639. resultList[eachIndex] = { error: { KeyNotMatch: true } };
  9640. nextItem(null);
  9641. return;
  9642. }
  9643. var UploadId = AbortItem.UploadId || AbortItem.UploadID;
  9644. self.multipartAbort({
  9645. Bucket: Bucket,
  9646. Region: Region,
  9647. Key: AbortItem.Key,
  9648. Headers: params.Headers,
  9649. UploadId: UploadId
  9650. }, function (err) {
  9651. var task = {
  9652. Bucket: Bucket,
  9653. Region: Region,
  9654. Key: AbortItem.Key,
  9655. UploadId: UploadId
  9656. };
  9657. resultList[eachIndex] = { error: err, task: task };
  9658. nextItem(null);
  9659. });
  9660. index++;
  9661. }, function (err) {
  9662. if (err) return callback(err);
  9663. var successList = [];
  9664. var errorList = [];
  9665. for (var i = 0, len = resultList.length; i < len; i++) {
  9666. var item = resultList[i];
  9667. if (item['task']) {
  9668. if (item['error']) {
  9669. errorList.push(item['task']);
  9670. } else {
  9671. successList.push(item['task']);
  9672. }
  9673. }
  9674. }
  9675. return callback(null, {
  9676. successList: successList,
  9677. errorList: errorList
  9678. });
  9679. });
  9680. }
  9681. // 高级上传
  9682. function uploadFile(params, callback) {
  9683. var self = this;
  9684. // 判断多大的文件使用分片上传
  9685. var SliceSize = params.SliceSize === undefined ? self.options.SliceSize : params.SliceSize;
  9686. var taskList = [];
  9687. var Body = params.Body;
  9688. var FileSize = Body.size || Body.length || 0;
  9689. var fileInfo = { TaskId: '' };
  9690. // 整理 option,用于返回给回调
  9691. util.each(params, function (v, k) {
  9692. if (typeof v !== 'object' && typeof v !== 'function') {
  9693. fileInfo[k] = v;
  9694. }
  9695. });
  9696. // 处理文件 TaskReady
  9697. var _onTaskReady = params.onTaskReady;
  9698. var onTaskReady = function (tid) {
  9699. fileInfo.TaskId = tid;
  9700. _onTaskReady && _onTaskReady(tid);
  9701. };
  9702. params.onTaskReady = onTaskReady;
  9703. // 处理文件完成
  9704. var _onFileFinish = params.onFileFinish;
  9705. var onFileFinish = function (err, data) {
  9706. _onFileFinish && _onFileFinish(err, data, fileInfo);
  9707. callback && callback(err, data);
  9708. };
  9709. // 添加上传任务,超过阈值使用分块上传,小于等于则简单上传
  9710. var api = FileSize > SliceSize ? 'sliceUploadFile' : 'putObject';
  9711. taskList.push({
  9712. api: api,
  9713. params: params,
  9714. callback: onFileFinish
  9715. });
  9716. self._addTasks(taskList);
  9717. }
  9718. // 批量上传文件
  9719. function uploadFiles(params, callback) {
  9720. var self = this;
  9721. // 判断多大的文件使用分片上传
  9722. var SliceSize = params.SliceSize === undefined ? self.options.SliceSize : params.SliceSize;
  9723. // 汇总返回进度
  9724. var TotalSize = 0;
  9725. var TotalFinish = 0;
  9726. var onTotalProgress = util.throttleOnProgress.call(self, TotalFinish, params.onProgress);
  9727. // 汇总返回回调
  9728. var unFinishCount = params.files.length;
  9729. var _onTotalFileFinish = params.onFileFinish;
  9730. var resultList = Array(unFinishCount);
  9731. var onTotalFileFinish = function (err, data, options) {
  9732. onTotalProgress(null, true);
  9733. _onTotalFileFinish && _onTotalFileFinish(err, data, options);
  9734. resultList[options.Index] = {
  9735. options: options,
  9736. error: err,
  9737. data: data
  9738. };
  9739. if (--unFinishCount <= 0 && callback) {
  9740. callback(null, { files: resultList });
  9741. }
  9742. };
  9743. // 开始处理每个文件
  9744. var taskList = [];
  9745. util.each(params.files, function (fileParams, index) {
  9746. (function () {
  9747. // 对齐 nodejs 缩进
  9748. var Body = fileParams.Body;
  9749. var FileSize = Body.size || Body.length || 0;
  9750. var fileInfo = { Index: index, TaskId: '' };
  9751. // 更新文件总大小
  9752. TotalSize += FileSize;
  9753. // 整理 option,用于返回给回调
  9754. util.each(fileParams, function (v, k) {
  9755. if (typeof v !== 'object' && typeof v !== 'function') {
  9756. fileInfo[k] = v;
  9757. }
  9758. });
  9759. // 处理单个文件 TaskReady
  9760. var _onTaskReady = fileParams.onTaskReady;
  9761. var onTaskReady = function (tid) {
  9762. fileInfo.TaskId = tid;
  9763. _onTaskReady && _onTaskReady(tid);
  9764. };
  9765. fileParams.onTaskReady = onTaskReady;
  9766. // 处理单个文件进度
  9767. var PreAddSize = 0;
  9768. var _onProgress = fileParams.onProgress;
  9769. var onProgress = function (info) {
  9770. TotalFinish = TotalFinish - PreAddSize + info.loaded;
  9771. PreAddSize = info.loaded;
  9772. _onProgress && _onProgress(info);
  9773. onTotalProgress({ loaded: TotalFinish, total: TotalSize });
  9774. };
  9775. fileParams.onProgress = onProgress;
  9776. // 处理单个文件完成
  9777. var _onFileFinish = fileParams.onFileFinish;
  9778. var onFileFinish = function (err, data) {
  9779. _onFileFinish && _onFileFinish(err, data);
  9780. onTotalFileFinish && onTotalFileFinish(err, data, fileInfo);
  9781. };
  9782. // 添加上传任务
  9783. var api = FileSize > SliceSize ? 'sliceUploadFile' : 'putObject';
  9784. taskList.push({
  9785. api: api,
  9786. params: fileParams,
  9787. callback: onFileFinish
  9788. });
  9789. })();
  9790. });
  9791. self._addTasks(taskList);
  9792. }
  9793. // 分片复制文件
  9794. function sliceCopyFile(params, callback) {
  9795. var ep = new EventProxy();
  9796. var self = this;
  9797. var Bucket = params.Bucket;
  9798. var Region = params.Region;
  9799. var Key = params.Key;
  9800. var CopySource = params.CopySource;
  9801. var m = util.getSourceParams.call(this, CopySource);
  9802. if (!m) {
  9803. callback(util.error(new Error('CopySource format error')));
  9804. return;
  9805. }
  9806. var SourceBucket = m.Bucket;
  9807. var SourceRegion = m.Region;
  9808. var SourceKey = decodeURIComponent(m.Key);
  9809. var CopySliceSize = params.CopySliceSize === undefined ? self.options.CopySliceSize : params.CopySliceSize;
  9810. CopySliceSize = Math.max(0, CopySliceSize);
  9811. var ChunkSize = params.CopyChunkSize || this.options.CopyChunkSize;
  9812. var ChunkParallel = this.options.CopyChunkParallelLimit;
  9813. var FinishSize = 0;
  9814. var FileSize;
  9815. var onProgress;
  9816. // 分片复制完成,开始 multipartComplete 操作
  9817. ep.on('copy_slice_complete', function (UploadData) {
  9818. var metaHeaders = {};
  9819. util.each(params.Headers, function (val, k) {
  9820. if (k.toLowerCase().indexOf('x-cos-meta-') === 0) metaHeaders[k] = val;
  9821. });
  9822. var Parts = util.map(UploadData.PartList, function (item) {
  9823. return {
  9824. PartNumber: item.PartNumber,
  9825. ETag: item.ETag
  9826. };
  9827. });
  9828. self.multipartComplete({
  9829. Bucket: Bucket,
  9830. Region: Region,
  9831. Key: Key,
  9832. UploadId: UploadData.UploadId,
  9833. Parts: Parts
  9834. }, function (err, data) {
  9835. if (err) {
  9836. onProgress(null, true);
  9837. return callback(err);
  9838. }
  9839. onProgress({ loaded: FileSize, total: FileSize }, true);
  9840. callback(null, data);
  9841. });
  9842. });
  9843. ep.on('get_copy_data_finish', function (UploadData) {
  9844. Async.eachLimit(UploadData.PartList, ChunkParallel, function (SliceItem, asyncCallback) {
  9845. var PartNumber = SliceItem.PartNumber;
  9846. var CopySourceRange = SliceItem.CopySourceRange;
  9847. var currentSize = SliceItem.end - SliceItem.start;
  9848. copySliceItem.call(self, {
  9849. Bucket: Bucket,
  9850. Region: Region,
  9851. Key: Key,
  9852. CopySource: CopySource,
  9853. UploadId: UploadData.UploadId,
  9854. PartNumber: PartNumber,
  9855. CopySourceRange: CopySourceRange
  9856. }, function (err, data) {
  9857. if (err) return asyncCallback(err);
  9858. FinishSize += currentSize;
  9859. onProgress({ loaded: FinishSize, total: FileSize });
  9860. SliceItem.ETag = data.ETag;
  9861. asyncCallback(err || null, data);
  9862. });
  9863. }, function (err) {
  9864. if (err) {
  9865. onProgress(null, true);
  9866. return callback(err);
  9867. }
  9868. ep.emit('copy_slice_complete', UploadData);
  9869. });
  9870. });
  9871. ep.on('get_file_size_finish', function (SourceHeaders) {
  9872. // 控制分片大小
  9873. (function () {
  9874. var SIZE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024 * 2, 1024 * 4, 1024 * 5];
  9875. var AutoChunkSize = 1024 * 1024;
  9876. for (var i = 0; i < SIZE.length; i++) {
  9877. AutoChunkSize = SIZE[i] * 1024 * 1024;
  9878. if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
  9879. }
  9880. params.ChunkSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
  9881. var ChunkCount = Math.ceil(FileSize / ChunkSize);
  9882. var list = [];
  9883. for (var partNumber = 1; partNumber <= ChunkCount; partNumber++) {
  9884. var start = (partNumber - 1) * ChunkSize;
  9885. var end = partNumber * ChunkSize < FileSize ? partNumber * ChunkSize - 1 : FileSize - 1;
  9886. var item = {
  9887. PartNumber: partNumber,
  9888. start: start,
  9889. end: end,
  9890. CopySourceRange: "bytes=" + start + "-" + end
  9891. };
  9892. list.push(item);
  9893. }
  9894. params.PartList = list;
  9895. })();
  9896. var TargetHeader;
  9897. if (params.Headers['x-cos-metadata-directive'] === 'Replaced') {
  9898. TargetHeader = params.Headers;
  9899. } else {
  9900. TargetHeader = SourceHeaders;
  9901. }
  9902. TargetHeader['x-cos-storage-class'] = params.Headers['x-cos-storage-class'] || SourceHeaders['x-cos-storage-class'];
  9903. TargetHeader = util.clearKey(TargetHeader);
  9904. /**
  9905. * 对于归档存储的对象,如果未恢复副本,则不允许 Copy
  9906. */
  9907. if (SourceHeaders['x-cos-storage-class'] === 'ARCHIVE' || SourceHeaders['x-cos-storage-class'] === 'DEEP_ARCHIVE') {
  9908. var restoreHeader = SourceHeaders['x-cos-restore'];
  9909. if (!restoreHeader || restoreHeader === 'ongoing-request="true"') {
  9910. callback(util.error(new Error('Unrestored archive object is not allowed to be copied')));
  9911. return;
  9912. }
  9913. }
  9914. /**
  9915. * 去除一些无用的头部,规避 multipartInit 出错
  9916. * 这些头部通常是在 putObjectCopy 时才使用
  9917. */
  9918. delete TargetHeader['x-cos-copy-source'];
  9919. delete TargetHeader['x-cos-metadata-directive'];
  9920. delete TargetHeader['x-cos-copy-source-If-Modified-Since'];
  9921. delete TargetHeader['x-cos-copy-source-If-Unmodified-Since'];
  9922. delete TargetHeader['x-cos-copy-source-If-Match'];
  9923. delete TargetHeader['x-cos-copy-source-If-None-Match'];
  9924. self.multipartInit({
  9925. Bucket: Bucket,
  9926. Region: Region,
  9927. Key: Key,
  9928. Headers: TargetHeader
  9929. }, function (err, data) {
  9930. if (err) return callback(err);
  9931. params.UploadId = data.UploadId;
  9932. ep.emit('get_copy_data_finish', params);
  9933. });
  9934. });
  9935. // 获取远端复制源文件的大小
  9936. self.headObject({
  9937. Bucket: SourceBucket,
  9938. Region: SourceRegion,
  9939. Key: SourceKey
  9940. }, function (err, data) {
  9941. if (err) {
  9942. if (err.statusCode && err.statusCode === 404) {
  9943. callback(util.error(err, { ErrorStatus: SourceKey + ' Not Exist' }));
  9944. } else {
  9945. callback(err);
  9946. }
  9947. return;
  9948. }
  9949. FileSize = params.FileSize = data.headers['content-length'];
  9950. if (FileSize === undefined || !FileSize) {
  9951. callback(util.error(new Error('get Content-Length error, please add "Content-Length" to CORS ExposeHeader setting.( 获取Content-Length失败,请在CORS ExposeHeader设置中添加Content-Length,请参考文档:https://cloud.tencent.com/document/product/436/13318 )')));
  9952. return;
  9953. }
  9954. onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
  9955. // 开始上传
  9956. if (FileSize <= CopySliceSize) {
  9957. if (!params.Headers['x-cos-metadata-directive']) {
  9958. params.Headers['x-cos-metadata-directive'] = 'Copy';
  9959. }
  9960. self.putObjectCopy(params, function (err, data) {
  9961. if (err) {
  9962. onProgress(null, true);
  9963. return callback(err);
  9964. }
  9965. onProgress({ loaded: FileSize, total: FileSize }, true);
  9966. callback(err, data);
  9967. });
  9968. } else {
  9969. var resHeaders = data.headers;
  9970. var SourceHeaders = {
  9971. 'Cache-Control': resHeaders['cache-control'],
  9972. 'Content-Disposition': resHeaders['content-disposition'],
  9973. 'Content-Encoding': resHeaders['content-encoding'],
  9974. 'Content-Type': resHeaders['content-type'],
  9975. 'Expires': resHeaders['expires'],
  9976. 'x-cos-storage-class': resHeaders['x-cos-storage-class']
  9977. };
  9978. util.each(resHeaders, function (v, k) {
  9979. var metaPrefix = 'x-cos-meta-';
  9980. if (k.indexOf(metaPrefix) === 0 && k.length > metaPrefix.length) {
  9981. SourceHeaders[k] = v;
  9982. }
  9983. });
  9984. ep.emit('get_file_size_finish', SourceHeaders);
  9985. }
  9986. });
  9987. }
  9988. // 复制指定分片
  9989. function copySliceItem(params, callback) {
  9990. var TaskId = params.TaskId;
  9991. var Bucket = params.Bucket;
  9992. var Region = params.Region;
  9993. var Key = params.Key;
  9994. var CopySource = params.CopySource;
  9995. var UploadId = params.UploadId;
  9996. var PartNumber = params.PartNumber * 1;
  9997. var CopySourceRange = params.CopySourceRange;
  9998. var ChunkRetryTimes = this.options.ChunkRetryTimes + 1;
  9999. var self = this;
  10000. Async.retry(ChunkRetryTimes, function (tryCallback) {
  10001. self.uploadPartCopy({
  10002. TaskId: TaskId,
  10003. Bucket: Bucket,
  10004. Region: Region,
  10005. Key: Key,
  10006. CopySource: CopySource,
  10007. UploadId: UploadId,
  10008. PartNumber: PartNumber,
  10009. CopySourceRange: CopySourceRange
  10010. }, function (err, data) {
  10011. tryCallback(err || null, data);
  10012. });
  10013. }, function (err, data) {
  10014. return callback(err, data);
  10015. });
  10016. }
  10017. var API_MAP = {
  10018. sliceUploadFile: sliceUploadFile,
  10019. abortUploadTask: abortUploadTask,
  10020. uploadFile: uploadFile,
  10021. uploadFiles: uploadFiles,
  10022. sliceCopyFile: sliceCopyFile
  10023. };
  10024. module.exports.init = function (COS, task) {
  10025. task.transferToTaskMethod(API_MAP, 'sliceUploadFile');
  10026. util.each(API_MAP, function (fn, apiName) {
  10027. COS.prototype[apiName] = util.apiWrapper(apiName, fn);
  10028. });
  10029. };
  10030. /***/ }),
  10031. /* 22 */
  10032. /***/ (function(module, exports) {
  10033. var eachLimit = function (arr, limit, iterator, callback) {
  10034. callback = callback || function () {};
  10035. if (!arr.length || limit <= 0) {
  10036. return callback();
  10037. }
  10038. var completed = 0;
  10039. var started = 0;
  10040. var running = 0;
  10041. (function replenish() {
  10042. if (completed >= arr.length) {
  10043. return callback();
  10044. }
  10045. while (running < limit && started < arr.length) {
  10046. started += 1;
  10047. running += 1;
  10048. iterator(arr[started - 1], function (err) {
  10049. if (err) {
  10050. callback(err);
  10051. callback = function () {};
  10052. } else {
  10053. completed += 1;
  10054. running -= 1;
  10055. if (completed >= arr.length) {
  10056. callback();
  10057. } else {
  10058. replenish();
  10059. }
  10060. }
  10061. });
  10062. }
  10063. })();
  10064. };
  10065. var retry = function (times, iterator, callback) {
  10066. var next = function (index) {
  10067. iterator(function (err, data) {
  10068. if (err && index < times) {
  10069. next(index + 1);
  10070. } else {
  10071. callback(err, data);
  10072. }
  10073. });
  10074. };
  10075. if (times < 1) {
  10076. callback();
  10077. } else {
  10078. next(1);
  10079. }
  10080. };
  10081. var async = {
  10082. eachLimit: eachLimit,
  10083. retry: retry
  10084. };
  10085. module.exports = async;
  10086. /***/ })
  10087. /******/ ]);
  10088. });