12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882 |
- (function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define([], factory);
- else if(typeof exports === 'object')
- exports["COS"] = factory();
- else
- root["COS"] = factory();
- })(typeof self !== 'undefined' ? self : this, function() {
- return /******/ (function(modules) { // webpackBootstrap
- /******/ // The module cache
- /******/ var installedModules = {};
- /******/
- /******/ // The require function
- /******/ function __webpack_require__(moduleId) {
- /******/
- /******/ // Check if module is in cache
- /******/ if(installedModules[moduleId]) {
- /******/ return installedModules[moduleId].exports;
- /******/ }
- /******/ // Create a new module (and put it into the cache)
- /******/ var module = installedModules[moduleId] = {
- /******/ i: moduleId,
- /******/ l: false,
- /******/ exports: {}
- /******/ };
- /******/
- /******/ // Execute the module function
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- /******/
- /******/ // Flag the module as loaded
- /******/ module.l = true;
- /******/
- /******/ // Return the exports of the module
- /******/ return module.exports;
- /******/ }
- /******/
- /******/
- /******/ // expose the modules object (__webpack_modules__)
- /******/ __webpack_require__.m = modules;
- /******/
- /******/ // expose the module cache
- /******/ __webpack_require__.c = installedModules;
- /******/
- /******/ // define getter function for harmony exports
- /******/ __webpack_require__.d = function(exports, name, getter) {
- /******/ if(!__webpack_require__.o(exports, name)) {
- /******/ Object.defineProperty(exports, name, {
- /******/ configurable: false,
- /******/ enumerable: true,
- /******/ get: getter
- /******/ });
- /******/ }
- /******/ };
- /******/
- /******/ // getDefaultExport function for compatibility with non-harmony modules
- /******/ __webpack_require__.n = function(module) {
- /******/ var getter = module && module.__esModule ?
- /******/ function getDefault() { return module['default']; } :
- /******/ function getModuleExports() { return module; };
- /******/ __webpack_require__.d(getter, 'a', getter);
- /******/ return getter;
- /******/ };
- /******/
- /******/ // Object.prototype.hasOwnProperty.call
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
- /******/
- /******/ // __webpack_public_path__
- /******/ __webpack_require__.p = "/dist/";
- /******/
- /******/ // Load entry module and return exports
- /******/ return __webpack_require__(__webpack_require__.s = 6);
- /******/ })
- /************************************************************************/
- /******/ ([
- /* 0 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- /* WEBPACK VAR INJECTION */(function(process) {
- var md5 = __webpack_require__(8);
- var CryptoJS = __webpack_require__(11);
- var xml2json = __webpack_require__(12);
- var json2xml = __webpack_require__(17);
- function camSafeUrlEncode(str) {
- return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A');
- }
- function getObjectKeys(obj, forKey) {
- var list = [];
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- list.push(forKey ? camSafeUrlEncode(key).toLowerCase() : key);
- }
- }
- return list.sort(function (a, b) {
- a = a.toLowerCase();
- b = b.toLowerCase();
- return a === b ? 0 : a > b ? 1 : -1;
- });
- };
- /**
- * obj转为string
- * @param {Object} obj 需要转的对象,必须
- * @param {Boolean} lowerCaseKey key是否转为小写,默认false,非必须
- * @return {String} data 返回字符串
- */
- var obj2str = function (obj, lowerCaseKey) {
- var i, key, val;
- var list = [];
- var keyList = getObjectKeys(obj);
- for (i = 0; i < keyList.length; i++) {
- key = keyList[i];
- val = obj[key] === undefined || obj[key] === null ? '' : '' + obj[key];
- key = lowerCaseKey ? camSafeUrlEncode(key).toLowerCase() : camSafeUrlEncode(key);
- val = camSafeUrlEncode(val) || '';
- list.push(key + '=' + val);
- }
- return list.join('&');
- };
- // 可以签入签名的headers
- 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'];
- var getSignHeaderObj = function (headers) {
- var signHeaderObj = {};
- for (var i in headers) {
- var key = i.toLowerCase();
- if (key.indexOf('x-cos-') > -1 || signHeaders.indexOf(key) > -1) {
- signHeaderObj[i] = headers[i];
- }
- }
- return signHeaderObj;
- };
- //测试用的key后面可以去掉
- var getAuth = function (opt) {
- opt = opt || {};
- var SecretId = opt.SecretId;
- var SecretKey = opt.SecretKey;
- var KeyTime = opt.KeyTime;
- var method = (opt.method || opt.Method || 'get').toLowerCase();
- var queryParams = clone(opt.Query || opt.params || {});
- var headers = getSignHeaderObj(clone(opt.Headers || opt.headers || {}));
- var Key = opt.Key || '';
- var pathname;
- if (opt.UseRawKey) {
- pathname = opt.Pathname || opt.pathname || '/' + Key;
- } else {
- pathname = opt.Pathname || opt.pathname || Key;
- pathname.indexOf('/') !== 0 && (pathname = '/' + pathname);
- }
- // ForceSignHost明确传入false才不加入host签名
- var forceSignHost = opt.ForceSignHost === false ? false : true;
- // 如果有传入存储桶且需要强制签名,那么签名默认加 Host 参与计算,避免跨桶访问
- if (!headers.Host && !headers.host && opt.Bucket && opt.Region && forceSignHost) headers.Host = opt.Bucket + '.cos.' + opt.Region + '.myqcloud.com';
- if (!SecretId) throw new Error('missing param SecretId');
- if (!SecretKey) throw new Error('missing param SecretKey');
- // 签名有效起止时间
- var now = Math.round(getSkewTime(opt.SystemClockOffset) / 1000) - 1;
- var exp = now;
- var Expires = opt.Expires || opt.expires;
- if (Expires === undefined) {
- exp += 900; // 签名过期时间为当前 + 900s
- } else {
- exp += Expires * 1 || 0;
- }
- // 要用到的 Authorization 参数列表
- var qSignAlgorithm = 'sha1';
- var qAk = SecretId;
- var qSignTime = KeyTime || now + ';' + exp;
- var qKeyTime = KeyTime || now + ';' + exp;
- var qHeaderList = getObjectKeys(headers, true).join(';').toLowerCase();
- var qUrlParamList = getObjectKeys(queryParams, true).join(';').toLowerCase();
- // 签名算法说明文档:https://www.qcloud.com/document/product/436/7778
- // 步骤一:计算 SignKey
- var signKey = CryptoJS.HmacSHA1(qKeyTime, SecretKey).toString();
- // 步骤二:构成 FormatString
- var formatString = [method, pathname, util.obj2str(queryParams, true), util.obj2str(headers, true), ''].join('\n');
- // 步骤三:计算 StringToSign
- var stringToSign = ['sha1', qSignTime, CryptoJS.SHA1(formatString).toString(), ''].join('\n');
- // 步骤四:计算 Signature
- var qSignature = CryptoJS.HmacSHA1(stringToSign, signKey).toString();
- // 步骤五:构造 Authorization
- 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('&');
- return authorization;
- };
- var readIntBE = function (chunk, size, offset) {
- var bytes = size / 8;
- var buf = chunk.slice(offset, offset + bytes);
- new Uint8Array(buf).reverse();
- return new { 8: Uint8Array, 16: Uint16Array, 32: Uint32Array }[size](buf)[0];
- };
- var buf2str = function (chunk, start, end, isUtf8) {
- var buf = chunk.slice(start, end);
- var str = '';
- new Uint8Array(buf).forEach(function (charCode) {
- str += String.fromCharCode(charCode);
- });
- if (isUtf8) str = decodeURIComponent(escape(str));
- return str;
- };
- var parseSelectPayload = function (chunk) {
- var header = {};
- var body = buf2str(chunk);
- var result = { records: [] };
- while (chunk.byteLength) {
- var totalLength = readIntBE(chunk, 32, 0);
- var headerLength = readIntBE(chunk, 32, 4);
- var payloadRestLength = totalLength - headerLength - 16;
- var offset = 0;
- var content;
- chunk = chunk.slice(12);
- // 获取 Message 的 header 信息
- while (offset < headerLength) {
- var headerNameLength = readIntBE(chunk, 8, offset);
- var headerName = buf2str(chunk, offset + 1, offset + 1 + headerNameLength);
- var headerValueLength = readIntBE(chunk, 16, offset + headerNameLength + 2);
- var headerValue = buf2str(chunk, offset + headerNameLength + 4, offset + headerNameLength + 4 + headerValueLength);
- header[headerName] = headerValue;
- offset += headerNameLength + 4 + headerValueLength;
- }
- if (header[':event-type'] === 'Records') {
- content = buf2str(chunk, offset, offset + payloadRestLength, true);
- result.records.push(content);
- } else if (header[':event-type'] === 'Stats') {
- content = buf2str(chunk, offset, offset + payloadRestLength, true);
- result.stats = util.xml2json(content).Stats;
- } else if (header[':event-type'] === 'error') {
- var errCode = header[':error-code'];
- var errMessage = header[':error-message'];
- var err = new Error(errMessage);
- err.message = errMessage;
- err.name = err.code = errCode;
- result.error = err;
- } else if (['Progress', 'Continuation', 'End'].includes(header[':event-type'])) {
- // do nothing
- }
- chunk = chunk.slice(offset + payloadRestLength + 4);
- }
- return {
- payload: result.records.join(''),
- body: body
- };
- };
- var getSourceParams = function (source) {
- var parser = this.options.CopySourceParser;
- if (parser) return parser(source);
- var m = source.match(/^([^.]+-\d+)\.cos(v6|-cdc)?\.([^.]+)\.myqcloud\.com\/(.+)$/);
- if (!m) return null;
- return { Bucket: m[1], Region: m[3], Key: m[4] };
- };
- var noop = function () {};
- // 清除对象里值为的 undefined 或 null 的属性
- var clearKey = function (obj) {
- var retObj = {};
- for (var key in obj) {
- if (obj.hasOwnProperty(key) && obj[key] !== undefined && obj[key] !== null) {
- retObj[key] = obj[key];
- }
- }
- return retObj;
- };
- var readAsBinaryString = function (blob, callback) {
- var readFun;
- var fr = new FileReader();
- if (FileReader.prototype.readAsBinaryString) {
- readFun = FileReader.prototype.readAsBinaryString;
- fr.onload = function () {
- callback(this.result);
- };
- } else if (FileReader.prototype.readAsArrayBuffer) {
- // 在 ie11 添加 readAsBinaryString 兼容
- readFun = function (fileData) {
- var binary = "";
- var pt = this;
- var reader = new FileReader();
- reader.onload = function (e) {
- var bytes = new Uint8Array(reader.result);
- var length = bytes.byteLength;
- for (var i = 0; i < length; i++) {
- binary += String.fromCharCode(bytes[i]);
- }
- callback(binary);
- };
- reader.readAsArrayBuffer(fileData);
- };
- } else {
- console.error('FileReader not support readAsBinaryString');
- }
- readFun.call(fr, blob);
- };
- var fileSliceNeedCopy = function () {
- var compareVersion = function (a, b) {
- a = a.split('.');
- b = b.split('.');
- for (var i = 0; i < b.length; i++) {
- if (a[i] !== b[i]) {
- return parseInt(a[i]) > parseInt(b[i]) ? 1 : -1;
- }
- }
- return 0;
- };
- var check = function (ua) {
- if (!ua) return false;
- var ChromeVersion = (ua.match(/Chrome\/([.\d]+)/) || [])[1];
- var QBCoreVersion = (ua.match(/QBCore\/([.\d]+)/) || [])[1];
- var QQBrowserVersion = (ua.match(/QQBrowser\/([.\d]+)/) || [])[1];
- 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;
- return need;
- };
- return check(typeof navigator !== 'undefined' && navigator.userAgent);
- }();
- // 获取文件分片
- var fileSlice = function (file, start, end, isUseToUpload, callback) {
- var blob;
- if (file.slice) {
- blob = file.slice(start, end);
- } else if (file.mozSlice) {
- blob = file.mozSlice(start, end);
- } else if (file.webkitSlice) {
- blob = file.webkitSlice(start, end);
- }
- if (isUseToUpload && fileSliceNeedCopy) {
- var reader = new FileReader();
- reader.onload = function (e) {
- blob = null;
- callback(new Blob([reader.result]));
- };
- reader.readAsArrayBuffer(blob);
- } else {
- callback(blob);
- }
- };
- // 获取文件内容的 MD5
- var getBodyMd5 = function (UploadCheckContentMd5, Body, callback, onProgress) {
- callback = callback || noop;
- if (UploadCheckContentMd5) {
- if (typeof Body === 'string') {
- callback(util.md5(Body, true));
- } else if (Blob && Body instanceof Blob) {
- util.getFileMd5(Body, function (err, md5) {
- callback(md5);
- }, onProgress);
- } else {
- callback();
- }
- } else {
- callback();
- }
- };
- // 获取文件 md5 值
- var md5ChunkSize = 1024 * 1024;
- var getFileMd5 = function (blob, callback, onProgress) {
- var size = blob.size;
- var loaded = 0;
- var md5ctx = md5.getCtx();
- var next = function (start) {
- if (start >= size) {
- var hash = md5ctx.digest('hex');
- callback(null, hash);
- return;
- }
- var end = Math.min(size, start + md5ChunkSize);
- util.fileSlice(blob, start, end, false, function (chunk) {
- readAsBinaryString(chunk, function (content) {
- chunk = null;
- md5ctx = md5ctx.update(content, true);
- loaded += content.length;
- content = null;
- if (onProgress) onProgress({ loaded: loaded, total: size, percent: Math.round(loaded / size * 10000) / 10000 });
- next(start + md5ChunkSize);
- });
- });
- };
- next(0);
- };
- function clone(obj) {
- return map(obj, function (v) {
- return typeof v === 'object' && v !== null ? clone(v) : v;
- });
- }
- function attr(obj, name, defaultValue) {
- return obj && name in obj ? obj[name] : defaultValue;
- }
- function extend(target, source) {
- each(source, function (val, key) {
- target[key] = source[key];
- });
- return target;
- }
- function isArray(arr) {
- return arr instanceof Array;
- }
- function isInArray(arr, item) {
- var flag = false;
- for (var i = 0; i < arr.length; i++) {
- if (item === arr[i]) {
- flag = true;
- break;
- }
- }
- return flag;
- }
- function makeArray(arr) {
- return isArray(arr) ? arr : [arr];
- }
- function each(obj, fn) {
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- fn(obj[i], i);
- }
- }
- }
- function map(obj, fn) {
- var o = isArray(obj) ? [] : {};
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- o[i] = fn(obj[i], i);
- }
- }
- return o;
- }
- function filter(obj, fn) {
- var iaArr = isArray(obj);
- var o = iaArr ? [] : {};
- for (var i in obj) {
- if (obj.hasOwnProperty(i)) {
- if (fn(obj[i], i)) {
- if (iaArr) {
- o.push(obj[i]);
- } else {
- o[i] = obj[i];
- }
- }
- }
- }
- return o;
- }
- var binaryBase64 = function (str) {
- var i,
- len,
- char,
- res = '';
- for (i = 0, len = str.length / 2; i < len; i++) {
- char = parseInt(str[i * 2] + str[i * 2 + 1], 16);
- res += String.fromCharCode(char);
- }
- return btoa(res);
- };
- var uuid = function () {
- var S4 = function () {
- return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
- };
- return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
- };
- var hasMissingParams = function (apiName, params) {
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var Domain = this.options.Domain;
- var checkBucket = !Domain || typeof Domain === 'string' && Domain.indexOf('{Bucket}') > -1;
- var checkRegion = !Domain || typeof Domain === 'string' && Domain.indexOf('{Region}') > -1;
- if (apiName.indexOf('Bucket') > -1 || apiName === 'deleteMultipleObject' || apiName === 'multipartList' || apiName === 'listObjectVersions') {
- if (checkBucket && !Bucket) return 'Bucket';
- if (checkRegion && !Region) return 'Region';
- } else if (apiName.indexOf('Object') > -1 || apiName.indexOf('multipart') > -1 || apiName === 'sliceUploadFile' || apiName === 'abortUploadTask') {
- if (checkBucket && !Bucket) return 'Bucket';
- if (checkRegion && !Region) return 'Region';
- if (!Key) return 'Key';
- }
- return false;
- };
- var formatParams = function (apiName, params) {
- // 复制参数对象
- params = extend({}, params);
- // 统一处理 Headers
- if (apiName !== 'getAuth' && apiName !== 'getV4Auth' && apiName !== 'getObjectUrl') {
- var Headers = params.Headers || {};
- if (params && typeof params === 'object') {
- (function () {
- for (var key in params) {
- if (params.hasOwnProperty(key) && key.indexOf('x-cos-') > -1) {
- Headers[key] = params[key];
- }
- }
- })();
- var headerMap = {
- // params headers
- 'x-cos-mfa': 'MFA',
- 'Content-MD5': 'ContentMD5',
- 'Content-Length': 'ContentLength',
- 'Content-Type': 'ContentType',
- 'Expect': 'Expect',
- 'Expires': 'Expires',
- 'Cache-Control': 'CacheControl',
- 'Content-Disposition': 'ContentDisposition',
- 'Content-Encoding': 'ContentEncoding',
- 'Range': 'Range',
- 'If-Modified-Since': 'IfModifiedSince',
- 'If-Unmodified-Since': 'IfUnmodifiedSince',
- 'If-Match': 'IfMatch',
- 'If-None-Match': 'IfNoneMatch',
- 'x-cos-copy-source': 'CopySource',
- 'x-cos-copy-source-Range': 'CopySourceRange',
- 'x-cos-metadata-directive': 'MetadataDirective',
- 'x-cos-copy-source-If-Modified-Since': 'CopySourceIfModifiedSince',
- 'x-cos-copy-source-If-Unmodified-Since': 'CopySourceIfUnmodifiedSince',
- 'x-cos-copy-source-If-Match': 'CopySourceIfMatch',
- 'x-cos-copy-source-If-None-Match': 'CopySourceIfNoneMatch',
- 'x-cos-acl': 'ACL',
- 'x-cos-grant-read': 'GrantRead',
- 'x-cos-grant-write': 'GrantWrite',
- 'x-cos-grant-full-control': 'GrantFullControl',
- 'x-cos-grant-read-acp': 'GrantReadAcp',
- 'x-cos-grant-write-acp': 'GrantWriteAcp',
- 'x-cos-storage-class': 'StorageClass',
- 'x-cos-traffic-limit': 'TrafficLimit',
- 'x-cos-mime-limit': 'MimeLimit',
- // SSE-C
- 'x-cos-server-side-encryption-customer-algorithm': 'SSECustomerAlgorithm',
- 'x-cos-server-side-encryption-customer-key': 'SSECustomerKey',
- 'x-cos-server-side-encryption-customer-key-MD5': 'SSECustomerKeyMD5',
- // SSE-COS、SSE-KMS
- 'x-cos-server-side-encryption': 'ServerSideEncryption',
- 'x-cos-server-side-encryption-cos-kms-key-id': 'SSEKMSKeyId',
- 'x-cos-server-side-encryption-context': 'SSEContext'
- };
- util.each(headerMap, function (paramKey, headerKey) {
- if (params[paramKey] !== undefined) {
- Headers[headerKey] = params[paramKey];
- }
- });
- params.Headers = clearKey(Headers);
- }
- }
- return params;
- };
- var apiWrapper = function (apiName, apiFn) {
- return function (params, callback) {
- var self = this;
- // 处理参数
- if (typeof params === 'function') {
- callback = params;
- params = {};
- }
- // 整理参数格式
- params = formatParams(apiName, params);
- // 代理回调函数
- var formatResult = function (result) {
- if (result && result.headers) {
- result.headers['x-cos-request-id'] && (result.RequestId = result.headers['x-cos-request-id']);
- result.headers['x-ci-request-id'] && (result.RequestId = result.headers['x-ci-request-id']);
- result.headers['x-cos-version-id'] && (result.VersionId = result.headers['x-cos-version-id']);
- result.headers['x-cos-delete-marker'] && (result.DeleteMarker = result.headers['x-cos-delete-marker']);
- }
- return result;
- };
- var _callback = function (err, data) {
- callback && callback(formatResult(err), formatResult(data));
- };
- var checkParams = function () {
- if (apiName !== 'getService' && apiName !== 'abortUploadTask') {
- // 判断参数是否完整
- var missingResult = hasMissingParams.call(self, apiName, params);
- if (missingResult) {
- return 'missing param ' + missingResult;
- }
- // 判断 region 格式
- if (params.Region) {
- if (self.options.CompatibilityMode) {
- if (!/^([a-z\d-.]+)$/.test(params.Region)) {
- return 'Region format error.';
- }
- } else {
- if (params.Region.indexOf('cos.') > -1) {
- return 'param Region should not be start with "cos."';
- } else if (!/^([a-z\d-]+)$/.test(params.Region)) {
- return 'Region format error.';
- }
- }
- // 判断 region 格式
- if (!self.options.CompatibilityMode && params.Region.indexOf('-') === -1 && params.Region !== 'yfb' && params.Region !== 'default' && params.Region !== 'accelerate') {
- console.warn('warning: param Region format error, find help here: https://cloud.tencent.com/document/product/436/6224');
- }
- }
- // 兼容不带 AppId 的 Bucket
- if (params.Bucket) {
- if (!/^([a-z\d-]+)-(\d+)$/.test(params.Bucket)) {
- if (params.AppId) {
- params.Bucket = params.Bucket + '-' + params.AppId;
- } else if (self.options.AppId) {
- params.Bucket = params.Bucket + '-' + self.options.AppId;
- } else {
- return 'Bucket should format as "test-1250000000".';
- }
- }
- if (params.AppId) {
- console.warn('warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g Bucket:"test-1250000000" ).');
- delete params.AppId;
- }
- }
- // 如果 Key 是 / 开头,强制去掉第一个 /
- if (!self.options.UseRawKey && params.Key && params.Key.substr(0, 1) === '/') {
- params.Key = params.Key.substr(1);
- }
- }
- };
- var errMsg = checkParams();
- var isSync = apiName === 'getAuth' || apiName === 'getObjectUrl';
- if (typeof Promise === 'function' && !isSync && !callback) {
- return new Promise(function (resolve, reject) {
- callback = function (err, data) {
- err ? reject(err) : resolve(data);
- };
- if (errMsg) return _callback(util.error(new Error(errMsg)));
- apiFn.call(self, params, _callback);
- });
- } else {
- if (errMsg) return _callback(util.error(new Error(errMsg)));
- var res = apiFn.call(self, params, _callback);
- if (isSync) return res;
- }
- };
- };
- var throttleOnProgress = function (total, onProgress) {
- var self = this;
- var size0 = 0;
- var size1 = 0;
- var time0 = Date.now();
- var time1;
- var timer;
- function update() {
- timer = 0;
- if (onProgress && typeof onProgress === 'function') {
- time1 = Date.now();
- var speed = Math.max(0, Math.round((size1 - size0) / ((time1 - time0) / 1000) * 100) / 100) || 0;
- var percent;
- if (size1 === 0 && total === 0) {
- percent = 1;
- } else {
- percent = Math.floor(size1 / total * 100) / 100 || 0;
- }
- time0 = time1;
- size0 = size1;
- try {
- onProgress({ loaded: size1, total: total, speed: speed, percent: percent });
- } catch (e) {}
- }
- }
- return function (info, immediately) {
- if (info) {
- size1 = info.loaded;
- total = info.total;
- }
- if (immediately) {
- clearTimeout(timer);
- update();
- } else {
- if (timer) return;
- timer = setTimeout(update, self.options.ProgressInterval);
- }
- };
- };
- var getFileSize = function (api, params, callback) {
- var size;
- if (typeof params.Body === 'string') {
- params.Body = new Blob([params.Body], { type: 'text/plain' });
- } else if (params.Body instanceof ArrayBuffer) {
- params.Body = new Blob([params.Body]);
- }
- if (params.Body && (params.Body instanceof Blob || params.Body.toString() === '[object File]' || params.Body.toString() === '[object Blob]')) {
- size = params.Body.size;
- } else {
- callback(util.error(new Error('params body format error, Only allow File|Blob|String.')));
- return;
- }
- params.ContentLength = size;
- callback(null, size);
- };
- // 获取调正的时间戳
- var getSkewTime = function (offset) {
- return Date.now() + (offset || 0);
- };
- var error = function (err, opt) {
- var sourceErr = err;
- err.message = err.message || null;
- if (typeof opt === 'string') {
- err.error = opt;
- err.message = opt;
- } else if (typeof opt === 'object' && opt !== null) {
- extend(err, opt);
- if (opt.code || opt.name) err.code = opt.code || opt.name;
- if (opt.message) err.message = opt.message;
- if (opt.stack) err.stack = opt.stack;
- }
- if (typeof Object.defineProperty === 'function') {
- Object.defineProperty(err, 'name', { writable: true, enumerable: false });
- Object.defineProperty(err, 'message', { enumerable: true });
- }
- err.name = opt && opt.name || err.name || err.code || 'Error';
- if (!err.code) err.code = err.name;
- if (!err.error) err.error = clone(sourceErr); // 兼容老的错误格式
- return err;
- };
- var isNode = function () {
- return typeof window !== 'object' && typeof process === 'object' && "function" === 'function';
- };
- var isCIHost = function (url) {
- return (/^https?:\/\/([^/]+\.)?ci\.[^/]+/.test(url)
- );
- };
- var util = {
- noop: noop,
- formatParams: formatParams,
- apiWrapper: apiWrapper,
- xml2json: xml2json,
- json2xml: json2xml,
- md5: md5,
- clearKey: clearKey,
- fileSlice: fileSlice,
- getBodyMd5: getBodyMd5,
- getFileMd5: getFileMd5,
- binaryBase64: binaryBase64,
- extend: extend,
- isArray: isArray,
- isInArray: isInArray,
- makeArray: makeArray,
- each: each,
- map: map,
- filter: filter,
- clone: clone,
- attr: attr,
- uuid: uuid,
- camSafeUrlEncode: camSafeUrlEncode,
- throttleOnProgress: throttleOnProgress,
- getFileSize: getFileSize,
- getSkewTime: getSkewTime,
- error: error,
- obj2str: obj2str,
- getAuth: getAuth,
- parseSelectPayload: parseSelectPayload,
- getSourceParams: getSourceParams,
- isBrowser: true,
- isNode: isNode,
- isCIHost: isCIHost
- };
- module.exports = util;
- /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2)))
- /***/ }),
- /* 1 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- /**
- * "Shallow freezes" an object to render it immutable.
- * Uses `Object.freeze` if available,
- * otherwise the immutability is only in the type.
- *
- * Is used to create "enum like" objects.
- *
- * @template T
- * @param {T} object the object to freeze
- * @param {Pick<ObjectConstructor, 'freeze'> = Object} oc `Object` by default,
- * allows to inject custom object constructor for tests
- * @returns {Readonly<T>}
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
- */
- function freeze(object, oc) {
- if (oc === undefined) {
- oc = Object
- }
- return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object
- }
- /**
- * Since we can not rely on `Object.assign` we provide a simplified version
- * that is sufficient for our needs.
- *
- * @param {Object} target
- * @param {Object | null | undefined} source
- *
- * @returns {Object} target
- * @throws TypeError if target is not an object
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
- * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign
- */
- function assign(target, source) {
- if (target === null || typeof target !== 'object') {
- throw new TypeError('target is not an object')
- }
- for (var key in source) {
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key]
- }
- }
- return target
- }
- /**
- * All mime types that are allowed as input to `DOMParser.parseFromString`
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 MDN
- * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype WHATWG HTML Spec
- * @see DOMParser.prototype.parseFromString
- */
- var MIME_TYPE = freeze({
- /**
- * `text/html`, the only mime type that triggers treating an XML document as HTML.
- *
- * @see DOMParser.SupportedType.isHTML
- * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
- * @see https://en.wikipedia.org/wiki/HTML Wikipedia
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
- * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec
- */
- HTML: 'text/html',
- /**
- * Helper method to check a mime type if it indicates an HTML document
- *
- * @param {string} [value]
- * @returns {boolean}
- *
- * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
- * @see https://en.wikipedia.org/wiki/HTML Wikipedia
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
- * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */
- isHTML: function (value) {
- return value === MIME_TYPE.HTML
- },
- /**
- * `application/xml`, the standard mime type for XML documents.
- *
- * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration
- * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303
- * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
- */
- XML_APPLICATION: 'application/xml',
- /**
- * `text/html`, an alias for `application/xml`.
- *
- * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303
- * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration
- * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
- */
- XML_TEXT: 'text/xml',
- /**
- * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace,
- * but is parsed as an XML document.
- *
- * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec
- * @see https://en.wikipedia.org/wiki/XHTML Wikipedia
- */
- XML_XHTML_APPLICATION: 'application/xhtml+xml',
- /**
- * `image/svg+xml`,
- *
- * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration
- * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1
- * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia
- */
- XML_SVG_IMAGE: 'image/svg+xml',
- })
- /**
- * Namespaces that are used in this code base.
- *
- * @see http://www.w3.org/TR/REC-xml-names
- */
- var NAMESPACE = freeze({
- /**
- * The XHTML namespace.
- *
- * @see http://www.w3.org/1999/xhtml
- */
- HTML: 'http://www.w3.org/1999/xhtml',
- /**
- * Checks if `uri` equals `NAMESPACE.HTML`.
- *
- * @param {string} [uri]
- *
- * @see NAMESPACE.HTML
- */
- isHTML: function (uri) {
- return uri === NAMESPACE.HTML
- },
- /**
- * The SVG namespace.
- *
- * @see http://www.w3.org/2000/svg
- */
- SVG: 'http://www.w3.org/2000/svg',
- /**
- * The `xml:` namespace.
- *
- * @see http://www.w3.org/XML/1998/namespace
- */
- XML: 'http://www.w3.org/XML/1998/namespace',
- /**
- * The `xmlns:` namespace
- *
- * @see https://www.w3.org/2000/xmlns/
- */
- XMLNS: 'http://www.w3.org/2000/xmlns/',
- })
- exports.assign = assign;
- exports.freeze = freeze;
- exports.MIME_TYPE = MIME_TYPE;
- exports.NAMESPACE = NAMESPACE;
- /***/ }),
- /* 2 */
- /***/ (function(module, exports) {
- // shim for using process in browser
- var process = module.exports = {};
- // cached from whatever global is present so that test runners that stub it
- // don't break things. But we need to wrap it in a try catch in case it is
- // wrapped in strict mode code which doesn't define any globals. It's inside a
- // function because try/catches deoptimize in certain engines.
- var cachedSetTimeout;
- var cachedClearTimeout;
- function defaultSetTimout() {
- throw new Error('setTimeout has not been defined');
- }
- function defaultClearTimeout () {
- throw new Error('clearTimeout has not been defined');
- }
- (function () {
- try {
- if (typeof setTimeout === 'function') {
- cachedSetTimeout = setTimeout;
- } else {
- cachedSetTimeout = defaultSetTimout;
- }
- } catch (e) {
- cachedSetTimeout = defaultSetTimout;
- }
- try {
- if (typeof clearTimeout === 'function') {
- cachedClearTimeout = clearTimeout;
- } else {
- cachedClearTimeout = defaultClearTimeout;
- }
- } catch (e) {
- cachedClearTimeout = defaultClearTimeout;
- }
- } ())
- function runTimeout(fun) {
- if (cachedSetTimeout === setTimeout) {
- //normal enviroments in sane situations
- return setTimeout(fun, 0);
- }
- // if setTimeout wasn't available but was latter defined
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
- cachedSetTimeout = setTimeout;
- return setTimeout(fun, 0);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedSetTimeout(fun, 0);
- } catch(e){
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedSetTimeout.call(null, fun, 0);
- } catch(e){
- // 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
- return cachedSetTimeout.call(this, fun, 0);
- }
- }
- }
- function runClearTimeout(marker) {
- if (cachedClearTimeout === clearTimeout) {
- //normal enviroments in sane situations
- return clearTimeout(marker);
- }
- // if clearTimeout wasn't available but was latter defined
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
- cachedClearTimeout = clearTimeout;
- return clearTimeout(marker);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedClearTimeout(marker);
- } catch (e){
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedClearTimeout.call(null, marker);
- } catch (e){
- // 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.
- // Some versions of I.E. have different rules for clearTimeout vs setTimeout
- return cachedClearTimeout.call(this, marker);
- }
- }
- }
- var queue = [];
- var draining = false;
- var currentQueue;
- var queueIndex = -1;
- function cleanUpNextTick() {
- if (!draining || !currentQueue) {
- return;
- }
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
- }
- function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = runTimeout(cleanUpNextTick);
- draining = true;
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- if (currentQueue) {
- currentQueue[queueIndex].run();
- }
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- runClearTimeout(timeout);
- }
- process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- runTimeout(drainQueue);
- }
- };
- // v8 likes predictible objects
- function Item(fun, array) {
- this.fun = fun;
- this.array = array;
- }
- Item.prototype.run = function () {
- this.fun.apply(null, this.array);
- };
- process.title = 'browser';
- process.browser = true;
- process.env = {};
- process.argv = [];
- process.version = ''; // empty string to avoid regexp issues
- process.versions = {};
- function noop() {}
- process.on = noop;
- process.addListener = noop;
- process.once = noop;
- process.off = noop;
- process.removeListener = noop;
- process.removeAllListeners = noop;
- process.emit = noop;
- process.prependListener = noop;
- process.prependOnceListener = noop;
- process.listeners = function (name) { return [] }
- process.binding = function (name) {
- throw new Error('process.binding is not supported');
- };
- process.cwd = function () { return '/' };
- process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
- };
- process.umask = function() { return 0; };
- /***/ }),
- /* 3 */
- /***/ (function(module, exports, __webpack_require__) {
- var conventions = __webpack_require__(1);
- var NAMESPACE = conventions.NAMESPACE;
- /**
- * A prerequisite for `[].filter`, to drop elements that are empty
- * @param {string} input
- * @returns {boolean}
- */
- function notEmptyString (input) {
- return input !== ''
- }
- /**
- * @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace
- * @see https://infra.spec.whatwg.org/#ascii-whitespace
- *
- * @param {string} input
- * @returns {string[]} (can be empty)
- */
- function splitOnASCIIWhitespace(input) {
- // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE
- return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : []
- }
- /**
- * Adds element as a key to current if it is not already present.
- *
- * @param {Record<string, boolean | undefined>} current
- * @param {string} element
- * @returns {Record<string, boolean | undefined>}
- */
- function orderedSetReducer (current, element) {
- if (!current.hasOwnProperty(element)) {
- current[element] = true;
- }
- return current;
- }
- /**
- * @see https://infra.spec.whatwg.org/#ordered-set
- * @param {string} input
- * @returns {string[]}
- */
- function toOrderedSet(input) {
- if (!input) return [];
- var list = splitOnASCIIWhitespace(input);
- return Object.keys(list.reduce(orderedSetReducer, {}))
- }
- /**
- * Uses `list.indexOf` to implement something like `Array.prototype.includes`,
- * which we can not rely on being available.
- *
- * @param {any[]} list
- * @returns {function(any): boolean}
- */
- function arrayIncludes (list) {
- return function(element) {
- return list && list.indexOf(element) !== -1;
- }
- }
- function copy(src,dest){
- for(var p in src){
- dest[p] = src[p];
- }
- }
- /**
- ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
- ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
- */
- function _extends(Class,Super){
- var pt = Class.prototype;
- if(!(pt instanceof Super)){
- function t(){};
- t.prototype = Super.prototype;
- t = new t();
- copy(pt,t);
- Class.prototype = pt = t;
- }
- if(pt.constructor != Class){
- if(typeof Class != 'function'){
- console.error("unknown Class:"+Class)
- }
- pt.constructor = Class
- }
- }
- // Node Types
- var NodeType = {}
- var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
- var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
- var TEXT_NODE = NodeType.TEXT_NODE = 3;
- var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
- var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
- var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
- var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
- var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
- var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
- var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
- var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
- var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
- // ExceptionCode
- var ExceptionCode = {}
- var ExceptionMessage = {};
- var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1);
- var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2);
- var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3);
- var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4);
- var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5);
- var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6);
- var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7);
- var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8);
- var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9);
- var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10);
- //level2
- var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11);
- var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12);
- var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13);
- var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14);
- var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15);
- /**
- * DOM Level 2
- * Object DOMException
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
- * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
- */
- function DOMException(code, message) {
- if(message instanceof Error){
- var error = message;
- }else{
- error = this;
- Error.call(this, ExceptionMessage[code]);
- this.message = ExceptionMessage[code];
- if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
- }
- error.code = code;
- if(message) this.message = this.message + ": " + message;
- return error;
- };
- DOMException.prototype = Error.prototype;
- copy(ExceptionCode,DOMException)
- /**
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
- * 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.
- * The items in the NodeList are accessible via an integral index, starting from 0.
- */
- function NodeList() {
- };
- NodeList.prototype = {
- /**
- * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
- * @standard level1
- */
- length:0,
- /**
- * 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.
- * @standard level1
- * @param index unsigned long
- * Index into the collection.
- * @return Node
- * The node at the indexth position in the NodeList, or null if that is not a valid index.
- */
- item: function(index) {
- return this[index] || null;
- },
- toString:function(isHTML,nodeFilter){
- for(var buf = [], i = 0;i<this.length;i++){
- serializeToString(this[i],buf,isHTML,nodeFilter);
- }
- return buf.join('');
- }
- };
- function LiveNodeList(node,refresh){
- this._node = node;
- this._refresh = refresh
- _updateLiveList(this);
- }
- function _updateLiveList(list){
- var inc = list._node._inc || list._node.ownerDocument._inc;
- if(list._inc != inc){
- var ls = list._refresh(list._node);
- //console.log(ls.length)
- __set__(list,'length',ls.length);
- copy(ls,list);
- list._inc = inc;
- }
- }
- LiveNodeList.prototype.item = function(i){
- _updateLiveList(this);
- return this[i];
- }
- _extends(LiveNodeList,NodeList);
- /**
- * Objects implementing the NamedNodeMap interface are used
- * to represent collections of nodes that can be accessed by name.
- * Note that NamedNodeMap does not inherit from NodeList;
- * NamedNodeMaps are not maintained in any particular order.
- * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index,
- * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap,
- * and does not imply that the DOM specifies an order to these Nodes.
- * NamedNodeMap objects in the DOM are live.
- * used for attributes or DocumentType entities
- */
- function NamedNodeMap() {
- };
- function _findNodeIndex(list,node){
- var i = list.length;
- while(i--){
- if(list[i] === node){return i}
- }
- }
- function _addNamedNode(el,list,newAttr,oldAttr){
- if(oldAttr){
- list[_findNodeIndex(list,oldAttr)] = newAttr;
- }else{
- list[list.length++] = newAttr;
- }
- if(el){
- newAttr.ownerElement = el;
- var doc = el.ownerDocument;
- if(doc){
- oldAttr && _onRemoveAttribute(doc,el,oldAttr);
- _onAddAttribute(doc,el,newAttr);
- }
- }
- }
- function _removeNamedNode(el,list,attr){
- //console.log('remove attr:'+attr)
- var i = _findNodeIndex(list,attr);
- if(i>=0){
- var lastIndex = list.length-1
- while(i<lastIndex){
- list[i] = list[++i]
- }
- list.length = lastIndex;
- if(el){
- var doc = el.ownerDocument;
- if(doc){
- _onRemoveAttribute(doc,el,attr);
- attr.ownerElement = null;
- }
- }
- }else{
- throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
- }
- }
- NamedNodeMap.prototype = {
- length:0,
- item:NodeList.prototype.item,
- getNamedItem: function(key) {
- // if(key.indexOf(':')>0 || key == 'xmlns'){
- // return null;
- // }
- //console.log()
- var i = this.length;
- while(i--){
- var attr = this[i];
- //console.log(attr.nodeName,key)
- if(attr.nodeName == key){
- return attr;
- }
- }
- },
- setNamedItem: function(attr) {
- var el = attr.ownerElement;
- if(el && el!=this._ownerElement){
- throw new DOMException(INUSE_ATTRIBUTE_ERR);
- }
- var oldAttr = this.getNamedItem(attr.nodeName);
- _addNamedNode(this._ownerElement,this,attr,oldAttr);
- return oldAttr;
- },
- /* returns Node */
- setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
- var el = attr.ownerElement, oldAttr;
- if(el && el!=this._ownerElement){
- throw new DOMException(INUSE_ATTRIBUTE_ERR);
- }
- oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
- _addNamedNode(this._ownerElement,this,attr,oldAttr);
- return oldAttr;
- },
- /* returns Node */
- removeNamedItem: function(key) {
- var attr = this.getNamedItem(key);
- _removeNamedNode(this._ownerElement,this,attr);
- return attr;
-
-
- },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
-
- //for level2
- removeNamedItemNS:function(namespaceURI,localName){
- var attr = this.getNamedItemNS(namespaceURI,localName);
- _removeNamedNode(this._ownerElement,this,attr);
- return attr;
- },
- getNamedItemNS: function(namespaceURI, localName) {
- var i = this.length;
- while(i--){
- var node = this[i];
- if(node.localName == localName && node.namespaceURI == namespaceURI){
- return node;
- }
- }
- return null;
- }
- };
- /**
- * The DOMImplementation interface represents an object providing methods
- * which are not dependent on any particular document.
- * Such an object is returned by the `Document.implementation` property.
- *
- * __The individual methods describe the differences compared to the specs.__
- *
- * @constructor
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN
- * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core (Initial)
- * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core
- * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core
- * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard
- */
- function DOMImplementation() {
- }
- DOMImplementation.prototype = {
- /**
- * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported.
- * The different implementations fairly diverged in what kind of features were reported.
- * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use.
- *
- * @deprecated It is deprecated and modern browsers return true in all cases.
- *
- * @param {string} feature
- * @param {string} [version]
- * @returns {boolean} always true
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
- * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
- */
- hasFeature: function(feature, version) {
- return true;
- },
- /**
- * Creates an XML Document object of the specified type with its document element.
- *
- * __It behaves slightly different from the description in the living standard__:
- * - There is no interface/class `XMLDocument`, it returns a `Document` instance.
- * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared.
- * - this implementation is not validating names or qualified names
- * (when parsing XML strings, the SAX parser takes care of that)
- *
- * @param {string|null} namespaceURI
- * @param {string} qualifiedName
- * @param {DocumentType=null} doctype
- * @returns {Document}
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
- * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial)
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core
- *
- * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
- * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
- * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
- */
- createDocument: function(namespaceURI, qualifiedName, doctype){
- var doc = new Document();
- doc.implementation = this;
- doc.childNodes = new NodeList();
- doc.doctype = doctype || null;
- if (doctype){
- doc.appendChild(doctype);
- }
- if (qualifiedName){
- var root = doc.createElementNS(namespaceURI, qualifiedName);
- doc.appendChild(root);
- }
- return doc;
- },
- /**
- * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`.
- *
- * __This behavior is slightly different from the in the specs__:
- * - this implementation is not validating names or qualified names
- * (when parsing XML strings, the SAX parser takes care of that)
- *
- * @param {string} qualifiedName
- * @param {string} [publicId]
- * @param {string} [systemId]
- * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation
- * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()`
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN
- * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core
- * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard
- *
- * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract
- * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names
- * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names
- */
- createDocumentType: function(qualifiedName, publicId, systemId){
- var node = new DocumentType();
- node.name = qualifiedName;
- node.nodeName = qualifiedName;
- node.publicId = publicId || '';
- node.systemId = systemId || '';
- return node;
- }
- };
- /**
- * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
- */
- function Node() {
- };
- Node.prototype = {
- firstChild : null,
- lastChild : null,
- previousSibling : null,
- nextSibling : null,
- attributes : null,
- parentNode : null,
- childNodes : null,
- ownerDocument : null,
- nodeValue : null,
- namespaceURI : null,
- prefix : null,
- localName : null,
- // Modified in DOM Level 2:
- insertBefore:function(newChild, refChild){//raises
- return _insertBefore(this,newChild,refChild);
- },
- replaceChild:function(newChild, oldChild){//raises
- this.insertBefore(newChild,oldChild);
- if(oldChild){
- this.removeChild(oldChild);
- }
- },
- removeChild:function(oldChild){
- return _removeChild(this,oldChild);
- },
- appendChild:function(newChild){
- return this.insertBefore(newChild,null);
- },
- hasChildNodes:function(){
- return this.firstChild != null;
- },
- cloneNode:function(deep){
- return cloneNode(this.ownerDocument||this,this,deep);
- },
- // Modified in DOM Level 2:
- normalize:function(){
- var child = this.firstChild;
- while(child){
- var next = child.nextSibling;
- if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
- this.removeChild(next);
- child.appendData(next.data);
- }else{
- child.normalize();
- child = next;
- }
- }
- },
- // Introduced in DOM Level 2:
- isSupported:function(feature, version){
- return this.ownerDocument.implementation.hasFeature(feature,version);
- },
- // Introduced in DOM Level 2:
- hasAttributes:function(){
- return this.attributes.length>0;
- },
- /**
- * Look up the prefix associated to the given namespace URI, starting from this node.
- * **The default namespace declarations are ignored by this method.**
- * See Namespace Prefix Lookup for details on the algorithm used by this method.
- *
- * _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._
- *
- * @param {string | null} namespaceURI
- * @returns {string | null}
- * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix
- * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo
- * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix
- * @see https://github.com/xmldom/xmldom/issues/322
- */
- lookupPrefix:function(namespaceURI){
- var el = this;
- while(el){
- var map = el._nsMap;
- //console.dir(map)
- if(map){
- for(var n in map){
- if(map[n] == namespaceURI){
- return n;
- }
- }
- }
- el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
- }
- return null;
- },
- // Introduced in DOM Level 3:
- lookupNamespaceURI:function(prefix){
- var el = this;
- while(el){
- var map = el._nsMap;
- //console.dir(map)
- if(map){
- if(prefix in map){
- return map[prefix] ;
- }
- }
- el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
- }
- return null;
- },
- // Introduced in DOM Level 3:
- isDefaultNamespace:function(namespaceURI){
- var prefix = this.lookupPrefix(namespaceURI);
- return prefix == null;
- }
- };
- function _xmlEncoder(c){
- return c == '<' && '<' ||
- c == '>' && '>' ||
- c == '&' && '&' ||
- c == '"' && '"' ||
- '&#'+c.charCodeAt()+';'
- }
- copy(NodeType,Node);
- copy(NodeType,Node.prototype);
- /**
- * @param callback return true for continue,false for break
- * @return boolean true: break visit;
- */
- function _visitNode(node,callback){
- if(callback(node)){
- return true;
- }
- if(node = node.firstChild){
- do{
- if(_visitNode(node,callback)){return true}
- }while(node=node.nextSibling)
- }
- }
- function Document(){
- }
- function _onAddAttribute(doc,el,newAttr){
- doc && doc._inc++;
- var ns = newAttr.namespaceURI ;
- if(ns === NAMESPACE.XMLNS){
- //update namespace
- el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value
- }
- }
- function _onRemoveAttribute(doc,el,newAttr,remove){
- doc && doc._inc++;
- var ns = newAttr.namespaceURI ;
- if(ns === NAMESPACE.XMLNS){
- //update namespace
- delete el._nsMap[newAttr.prefix?newAttr.localName:'']
- }
- }
- /**
- * Updates `el.childNodes`, updating the indexed items and it's `length`.
- * Passing `newChild` means it will be appended.
- * Otherwise it's assumed that an item has been removed,
- * and `el.firstNode` and it's `.nextSibling` are used
- * to walk the current list of child nodes.
- *
- * @param {Document} doc
- * @param {Node} el
- * @param {Node} [newChild]
- * @private
- */
- function _onUpdateChild (doc, el, newChild) {
- if(doc && doc._inc){
- doc._inc++;
- //update childNodes
- var cs = el.childNodes;
- if (newChild) {
- cs[cs.length++] = newChild;
- } else {
- var child = el.firstChild;
- var i = 0;
- while (child) {
- cs[i++] = child;
- child = child.nextSibling;
- }
- cs.length = i;
- delete cs[cs.length];
- }
- }
- }
- /**
- * Removes the connections between `parentNode` and `child`
- * and any existing `child.previousSibling` or `child.nextSibling`.
- *
- * @see https://github.com/xmldom/xmldom/issues/135
- * @see https://github.com/xmldom/xmldom/issues/145
- *
- * @param {Node} parentNode
- * @param {Node} child
- * @returns {Node} the child that was removed.
- * @private
- */
- function _removeChild (parentNode, child) {
- var previous = child.previousSibling;
- var next = child.nextSibling;
- if (previous) {
- previous.nextSibling = next;
- } else {
- parentNode.firstChild = next;
- }
- if (next) {
- next.previousSibling = previous;
- } else {
- parentNode.lastChild = previous;
- }
- child.parentNode = null;
- child.previousSibling = null;
- child.nextSibling = null;
- _onUpdateChild(parentNode.ownerDocument, parentNode);
- return child;
- }
- /**
- * preformance key(refChild == null)
- */
- function _insertBefore(parentNode,newChild,nextChild){
- var cp = newChild.parentNode;
- if(cp){
- cp.removeChild(newChild);//remove and update
- }
- if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
- var newFirst = newChild.firstChild;
- if (newFirst == null) {
- return newChild;
- }
- var newLast = newChild.lastChild;
- }else{
- newFirst = newLast = newChild;
- }
- var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
- newFirst.previousSibling = pre;
- newLast.nextSibling = nextChild;
-
-
- if(pre){
- pre.nextSibling = newFirst;
- }else{
- parentNode.firstChild = newFirst;
- }
- if(nextChild == null){
- parentNode.lastChild = newLast;
- }else{
- nextChild.previousSibling = newLast;
- }
- do{
- newFirst.parentNode = parentNode;
- }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
- _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
- //console.log(parentNode.lastChild.nextSibling == null)
- if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
- newChild.firstChild = newChild.lastChild = null;
- }
- return newChild;
- }
- /**
- * Appends `newChild` to `parentNode`.
- * If `newChild` is already connected to a `parentNode` it is first removed from it.
- *
- * @see https://github.com/xmldom/xmldom/issues/135
- * @see https://github.com/xmldom/xmldom/issues/145
- * @param {Node} parentNode
- * @param {Node} newChild
- * @returns {Node}
- * @private
- */
- function _appendSingleChild (parentNode, newChild) {
- if (newChild.parentNode) {
- newChild.parentNode.removeChild(newChild);
- }
- newChild.parentNode = parentNode;
- newChild.previousSibling = parentNode.lastChild;
- newChild.nextSibling = null;
- if (newChild.previousSibling) {
- newChild.previousSibling.nextSibling = newChild;
- } else {
- parentNode.firstChild = newChild;
- }
- parentNode.lastChild = newChild;
- _onUpdateChild(parentNode.ownerDocument, parentNode, newChild);
- return newChild;
- }
- Document.prototype = {
- //implementation : null,
- nodeName : '#document',
- nodeType : DOCUMENT_NODE,
- /**
- * The DocumentType node of the document.
- *
- * @readonly
- * @type DocumentType
- */
- doctype : null,
- documentElement : null,
- _inc : 1,
- insertBefore : function(newChild, refChild){//raises
- if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
- var child = newChild.firstChild;
- while(child){
- var next = child.nextSibling;
- this.insertBefore(child,refChild);
- child = next;
- }
- return newChild;
- }
- if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
- this.documentElement = newChild;
- }
- return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild;
- },
- removeChild : function(oldChild){
- if(this.documentElement == oldChild){
- this.documentElement = null;
- }
- return _removeChild(this,oldChild);
- },
- // Introduced in DOM Level 2:
- importNode : function(importedNode,deep){
- return importNode(this,importedNode,deep);
- },
- // Introduced in DOM Level 2:
- getElementById : function(id){
- var rtv = null;
- _visitNode(this.documentElement,function(node){
- if(node.nodeType == ELEMENT_NODE){
- if(node.getAttribute('id') == id){
- rtv = node;
- return true;
- }
- }
- })
- return rtv;
- },
- /**
- * The `getElementsByClassName` method of `Document` interface returns an array-like object
- * of all child elements which have **all** of the given class name(s).
- *
- * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters.
- *
- *
- * Warning: This is a live LiveNodeList.
- * Changes in the DOM will reflect in the array as the changes occur.
- * If an element selected by this array no longer qualifies for the selector,
- * it will automatically be removed. Be aware of this for iteration purposes.
- *
- * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
- * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
- */
- getElementsByClassName: function(classNames) {
- var classNamesSet = toOrderedSet(classNames)
- return new LiveNodeList(this, function(base) {
- var ls = [];
- if (classNamesSet.length > 0) {
- _visitNode(base.documentElement, function(node) {
- if(node !== base && node.nodeType === ELEMENT_NODE) {
- var nodeClassNames = node.getAttribute('class')
- // can be null if the attribute does not exist
- if (nodeClassNames) {
- // before splitting and iterating just compare them for the most common case
- var matches = classNames === nodeClassNames;
- if (!matches) {
- var nodeClassNamesSet = toOrderedSet(nodeClassNames)
- matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet))
- }
- if(matches) {
- ls.push(node);
- }
- }
- }
- });
- }
- return ls;
- });
- },
- //document factory method:
- createElement : function(tagName){
- var node = new Element();
- node.ownerDocument = this;
- node.nodeName = tagName;
- node.tagName = tagName;
- node.localName = tagName;
- node.childNodes = new NodeList();
- var attrs = node.attributes = new NamedNodeMap();
- attrs._ownerElement = node;
- return node;
- },
- createDocumentFragment : function(){
- var node = new DocumentFragment();
- node.ownerDocument = this;
- node.childNodes = new NodeList();
- return node;
- },
- createTextNode : function(data){
- var node = new Text();
- node.ownerDocument = this;
- node.appendData(data)
- return node;
- },
- createComment : function(data){
- var node = new Comment();
- node.ownerDocument = this;
- node.appendData(data)
- return node;
- },
- createCDATASection : function(data){
- var node = new CDATASection();
- node.ownerDocument = this;
- node.appendData(data)
- return node;
- },
- createProcessingInstruction : function(target,data){
- var node = new ProcessingInstruction();
- node.ownerDocument = this;
- node.tagName = node.target = target;
- node.nodeValue= node.data = data;
- return node;
- },
- createAttribute : function(name){
- var node = new Attr();
- node.ownerDocument = this;
- node.name = name;
- node.nodeName = name;
- node.localName = name;
- node.specified = true;
- return node;
- },
- createEntityReference : function(name){
- var node = new EntityReference();
- node.ownerDocument = this;
- node.nodeName = name;
- return node;
- },
- // Introduced in DOM Level 2:
- createElementNS : function(namespaceURI,qualifiedName){
- var node = new Element();
- var pl = qualifiedName.split(':');
- var attrs = node.attributes = new NamedNodeMap();
- node.childNodes = new NodeList();
- node.ownerDocument = this;
- node.nodeName = qualifiedName;
- node.tagName = qualifiedName;
- node.namespaceURI = namespaceURI;
- if(pl.length == 2){
- node.prefix = pl[0];
- node.localName = pl[1];
- }else{
- //el.prefix = null;
- node.localName = qualifiedName;
- }
- attrs._ownerElement = node;
- return node;
- },
- // Introduced in DOM Level 2:
- createAttributeNS : function(namespaceURI,qualifiedName){
- var node = new Attr();
- var pl = qualifiedName.split(':');
- node.ownerDocument = this;
- node.nodeName = qualifiedName;
- node.name = qualifiedName;
- node.namespaceURI = namespaceURI;
- node.specified = true;
- if(pl.length == 2){
- node.prefix = pl[0];
- node.localName = pl[1];
- }else{
- //el.prefix = null;
- node.localName = qualifiedName;
- }
- return node;
- }
- };
- _extends(Document,Node);
- function Element() {
- this._nsMap = {};
- };
- Element.prototype = {
- nodeType : ELEMENT_NODE,
- hasAttribute : function(name){
- return this.getAttributeNode(name)!=null;
- },
- getAttribute : function(name){
- var attr = this.getAttributeNode(name);
- return attr && attr.value || '';
- },
- getAttributeNode : function(name){
- return this.attributes.getNamedItem(name);
- },
- setAttribute : function(name, value){
- var attr = this.ownerDocument.createAttribute(name);
- attr.value = attr.nodeValue = "" + value;
- this.setAttributeNode(attr)
- },
- removeAttribute : function(name){
- var attr = this.getAttributeNode(name)
- attr && this.removeAttributeNode(attr);
- },
-
- //four real opeartion method
- appendChild:function(newChild){
- if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
- return this.insertBefore(newChild,null);
- }else{
- return _appendSingleChild(this,newChild);
- }
- },
- setAttributeNode : function(newAttr){
- return this.attributes.setNamedItem(newAttr);
- },
- setAttributeNodeNS : function(newAttr){
- return this.attributes.setNamedItemNS(newAttr);
- },
- removeAttributeNode : function(oldAttr){
- //console.log(this == oldAttr.ownerElement)
- return this.attributes.removeNamedItem(oldAttr.nodeName);
- },
- //get real attribute name,and remove it by removeAttributeNode
- removeAttributeNS : function(namespaceURI, localName){
- var old = this.getAttributeNodeNS(namespaceURI, localName);
- old && this.removeAttributeNode(old);
- },
-
- hasAttributeNS : function(namespaceURI, localName){
- return this.getAttributeNodeNS(namespaceURI, localName)!=null;
- },
- getAttributeNS : function(namespaceURI, localName){
- var attr = this.getAttributeNodeNS(namespaceURI, localName);
- return attr && attr.value || '';
- },
- setAttributeNS : function(namespaceURI, qualifiedName, value){
- var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
- attr.value = attr.nodeValue = "" + value;
- this.setAttributeNode(attr)
- },
- getAttributeNodeNS : function(namespaceURI, localName){
- return this.attributes.getNamedItemNS(namespaceURI, localName);
- },
-
- getElementsByTagName : function(tagName){
- return new LiveNodeList(this,function(base){
- var ls = [];
- _visitNode(base,function(node){
- if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
- ls.push(node);
- }
- });
- return ls;
- });
- },
- getElementsByTagNameNS : function(namespaceURI, localName){
- return new LiveNodeList(this,function(base){
- var ls = [];
- _visitNode(base,function(node){
- if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
- ls.push(node);
- }
- });
- return ls;
-
- });
- }
- };
- Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
- Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
- _extends(Element,Node);
- function Attr() {
- };
- Attr.prototype.nodeType = ATTRIBUTE_NODE;
- _extends(Attr,Node);
- function CharacterData() {
- };
- CharacterData.prototype = {
- data : '',
- substringData : function(offset, count) {
- return this.data.substring(offset, offset+count);
- },
- appendData: function(text) {
- text = this.data+text;
- this.nodeValue = this.data = text;
- this.length = text.length;
- },
- insertData: function(offset,text) {
- this.replaceData(offset,0,text);
-
- },
- appendChild:function(newChild){
- throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
- },
- deleteData: function(offset, count) {
- this.replaceData(offset,count,"");
- },
- replaceData: function(offset, count, text) {
- var start = this.data.substring(0,offset);
- var end = this.data.substring(offset+count);
- text = start + text + end;
- this.nodeValue = this.data = text;
- this.length = text.length;
- }
- }
- _extends(CharacterData,Node);
- function Text() {
- };
- Text.prototype = {
- nodeName : "#text",
- nodeType : TEXT_NODE,
- splitText : function(offset) {
- var text = this.data;
- var newText = text.substring(offset);
- text = text.substring(0, offset);
- this.data = this.nodeValue = text;
- this.length = text.length;
- var newNode = this.ownerDocument.createTextNode(newText);
- if(this.parentNode){
- this.parentNode.insertBefore(newNode, this.nextSibling);
- }
- return newNode;
- }
- }
- _extends(Text,CharacterData);
- function Comment() {
- };
- Comment.prototype = {
- nodeName : "#comment",
- nodeType : COMMENT_NODE
- }
- _extends(Comment,CharacterData);
- function CDATASection() {
- };
- CDATASection.prototype = {
- nodeName : "#cdata-section",
- nodeType : CDATA_SECTION_NODE
- }
- _extends(CDATASection,CharacterData);
- function DocumentType() {
- };
- DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
- _extends(DocumentType,Node);
- function Notation() {
- };
- Notation.prototype.nodeType = NOTATION_NODE;
- _extends(Notation,Node);
- function Entity() {
- };
- Entity.prototype.nodeType = ENTITY_NODE;
- _extends(Entity,Node);
- function EntityReference() {
- };
- EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
- _extends(EntityReference,Node);
- function DocumentFragment() {
- };
- DocumentFragment.prototype.nodeName = "#document-fragment";
- DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
- _extends(DocumentFragment,Node);
- function ProcessingInstruction() {
- }
- ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
- _extends(ProcessingInstruction,Node);
- function XMLSerializer(){}
- XMLSerializer.prototype.serializeToString = function(node,isHtml,nodeFilter){
- return nodeSerializeToString.call(node,isHtml,nodeFilter);
- }
- Node.prototype.toString = nodeSerializeToString;
- function nodeSerializeToString(isHtml,nodeFilter){
- var buf = [];
- var refNode = this.nodeType == 9 && this.documentElement || this;
- var prefix = refNode.prefix;
- var uri = refNode.namespaceURI;
-
- if(uri && prefix == null){
- //console.log(prefix)
- var prefix = refNode.lookupPrefix(uri);
- if(prefix == null){
- //isHTML = true;
- var visibleNamespaces=[
- {namespace:uri,prefix:null}
- //{namespace:uri,prefix:''}
- ]
- }
- }
- serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
- //console.log('###',this.nodeType,uri,prefix,buf.join(''))
- return buf.join('');
- }
- function needNamespaceDefine(node, isHTML, visibleNamespaces) {
- var prefix = node.prefix || '';
- var uri = node.namespaceURI;
- // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) ,
- // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl :
- // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty.
- // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using)
- // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared :
- // > [...] Furthermore, the attribute value [...] must not be an empty string.
- // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document.
- if (!uri) {
- return false;
- }
- if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) {
- return false;
- }
-
- var i = visibleNamespaces.length
- while (i--) {
- var ns = visibleNamespaces[i];
- // get namespace prefix
- if (ns.prefix === prefix) {
- return ns.namespace !== uri;
- }
- }
- return true;
- }
- /**
- * Well-formed constraint: No < in Attribute Values
- * > The replacement text of any entity referred to directly or indirectly
- * > in an attribute value must not contain a <.
- * @see https://www.w3.org/TR/xml11/#CleanAttrVals
- * @see https://www.w3.org/TR/xml11/#NT-AttValue
- *
- * Literal whitespace other than space that appear in attribute values
- * are serialized as their entity references, so they will be preserved.
- * (In contrast to whitespace literals in the input which are normalized to spaces)
- * @see https://www.w3.org/TR/xml11/#AVNormalize
- * @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes
- */
- function addSerializedAttribute(buf, qualifiedName, value) {
- buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"')
- }
- function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
- if (!visibleNamespaces) {
- visibleNamespaces = [];
- }
- if(nodeFilter){
- node = nodeFilter(node);
- if(node){
- if(typeof node == 'string'){
- buf.push(node);
- return;
- }
- }else{
- return;
- }
- //buf.sort.apply(attrs, attributeSorter);
- }
- switch(node.nodeType){
- case ELEMENT_NODE:
- var attrs = node.attributes;
- var len = attrs.length;
- var child = node.firstChild;
- var nodeName = node.tagName;
-
- isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML
- var prefixedNodeName = nodeName
- if (!isHTML && !node.prefix && node.namespaceURI) {
- var defaultNS
- // lookup current default ns from `xmlns` attribute
- for (var ai = 0; ai < attrs.length; ai++) {
- if (attrs.item(ai).name === 'xmlns') {
- defaultNS = attrs.item(ai).value
- break
- }
- }
- if (!defaultNS) {
- // lookup current default ns in visibleNamespaces
- for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
- var namespace = visibleNamespaces[nsi]
- if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) {
- defaultNS = namespace.namespace
- break
- }
- }
- }
- if (defaultNS !== node.namespaceURI) {
- for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) {
- var namespace = visibleNamespaces[nsi]
- if (namespace.namespace === node.namespaceURI) {
- if (namespace.prefix) {
- prefixedNodeName = namespace.prefix + ':' + nodeName
- }
- break
- }
- }
- }
- }
- buf.push('<', prefixedNodeName);
- for(var i=0;i<len;i++){
- // add namespaces for attributes
- var attr = attrs.item(i);
- if (attr.prefix == 'xmlns') {
- visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
- }else if(attr.nodeName == 'xmlns'){
- visibleNamespaces.push({ prefix: '', namespace: attr.value });
- }
- }
- for(var i=0;i<len;i++){
- var attr = attrs.item(i);
- if (needNamespaceDefine(attr,isHTML, visibleNamespaces)) {
- var prefix = attr.prefix||'';
- var uri = attr.namespaceURI;
- addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
- visibleNamespaces.push({ prefix: prefix, namespace:uri });
- }
- serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
- }
- // add namespace for current node
- if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) {
- var prefix = node.prefix||'';
- var uri = node.namespaceURI;
- addSerializedAttribute(buf, prefix ? 'xmlns:' + prefix : "xmlns", uri);
- visibleNamespaces.push({ prefix: prefix, namespace:uri });
- }
-
- if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
- buf.push('>');
- //if is cdata child node
- if(isHTML && /^script$/i.test(nodeName)){
- while(child){
- if(child.data){
- buf.push(child.data);
- }else{
- serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
- }
- child = child.nextSibling;
- }
- }else
- {
- while(child){
- serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
- child = child.nextSibling;
- }
- }
- buf.push('</',prefixedNodeName,'>');
- }else{
- buf.push('/>');
- }
- // remove added visible namespaces
- //visibleNamespaces.length = startVisibleNamespaces;
- return;
- case DOCUMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- var child = node.firstChild;
- while(child){
- serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice());
- child = child.nextSibling;
- }
- return;
- case ATTRIBUTE_NODE:
- return addSerializedAttribute(buf, node.name, node.value);
- case TEXT_NODE:
- /**
- * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form,
- * except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section.
- * If they are needed elsewhere, they must be escaped using either numeric character references or the strings
- * `&` and `<` respectively.
- * The right angle bracket (>) may be represented using the string " > ", and must, for compatibility,
- * be escaped using either `>` or a character reference when it appears in the string `]]>` in content,
- * when that string is not marking the end of a CDATA section.
- *
- * In the content of elements, character data is any string of characters
- * which does not contain the start-delimiter of any markup
- * and does not include the CDATA-section-close delimiter, `]]>`.
- *
- * @see https://www.w3.org/TR/xml/#NT-CharData
- * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node
- */
- return buf.push(node.data
- .replace(/[<&>]/g,_xmlEncoder)
- );
- case CDATA_SECTION_NODE:
- return buf.push( '<![CDATA[',node.data,']]>');
- case COMMENT_NODE:
- return buf.push( "<!--",node.data,"-->");
- case DOCUMENT_TYPE_NODE:
- var pubid = node.publicId;
- var sysid = node.systemId;
- buf.push('<!DOCTYPE ',node.name);
- if(pubid){
- buf.push(' PUBLIC ', pubid);
- if (sysid && sysid!='.') {
- buf.push(' ', sysid);
- }
- buf.push('>');
- }else if(sysid && sysid!='.'){
- buf.push(' SYSTEM ', sysid, '>');
- }else{
- var sub = node.internalSubset;
- if(sub){
- buf.push(" [",sub,"]");
- }
- buf.push(">");
- }
- return;
- case PROCESSING_INSTRUCTION_NODE:
- return buf.push( "<?",node.target," ",node.data,"?>");
- case ENTITY_REFERENCE_NODE:
- return buf.push( '&',node.nodeName,';');
- //case ENTITY_NODE:
- //case NOTATION_NODE:
- default:
- buf.push('??',node.nodeName);
- }
- }
- function importNode(doc,node,deep){
- var node2;
- switch (node.nodeType) {
- case ELEMENT_NODE:
- node2 = node.cloneNode(false);
- node2.ownerDocument = doc;
- //var attrs = node2.attributes;
- //var len = attrs.length;
- //for(var i=0;i<len;i++){
- //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
- //}
- case DOCUMENT_FRAGMENT_NODE:
- break;
- case ATTRIBUTE_NODE:
- deep = true;
- break;
- //case ENTITY_REFERENCE_NODE:
- //case PROCESSING_INSTRUCTION_NODE:
- ////case TEXT_NODE:
- //case CDATA_SECTION_NODE:
- //case COMMENT_NODE:
- // deep = false;
- // break;
- //case DOCUMENT_NODE:
- //case DOCUMENT_TYPE_NODE:
- //cannot be imported.
- //case ENTITY_NODE:
- //case NOTATION_NODE:
- //can not hit in level3
- //default:throw e;
- }
- if(!node2){
- node2 = node.cloneNode(false);//false
- }
- node2.ownerDocument = doc;
- node2.parentNode = null;
- if(deep){
- var child = node.firstChild;
- while(child){
- node2.appendChild(importNode(doc,child,deep));
- child = child.nextSibling;
- }
- }
- return node2;
- }
- //
- //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
- // attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
- function cloneNode(doc,node,deep){
- var node2 = new node.constructor();
- for(var n in node){
- var v = node[n];
- if(typeof v != 'object' ){
- if(v != node2[n]){
- node2[n] = v;
- }
- }
- }
- if(node.childNodes){
- node2.childNodes = new NodeList();
- }
- node2.ownerDocument = doc;
- switch (node2.nodeType) {
- case ELEMENT_NODE:
- var attrs = node.attributes;
- var attrs2 = node2.attributes = new NamedNodeMap();
- var len = attrs.length
- attrs2._ownerElement = node2;
- for(var i=0;i<len;i++){
- node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
- }
- break;;
- case ATTRIBUTE_NODE:
- deep = true;
- }
- if(deep){
- var child = node.firstChild;
- while(child){
- node2.appendChild(cloneNode(doc,child,deep));
- child = child.nextSibling;
- }
- }
- return node2;
- }
- function __set__(object,key,value){
- object[key] = value
- }
- //do dynamic
- try{
- if(Object.defineProperty){
- Object.defineProperty(LiveNodeList.prototype,'length',{
- get:function(){
- _updateLiveList(this);
- return this.$$length;
- }
- });
- Object.defineProperty(Node.prototype,'textContent',{
- get:function(){
- return getTextContent(this);
- },
- set:function(data){
- switch(this.nodeType){
- case ELEMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- while(this.firstChild){
- this.removeChild(this.firstChild);
- }
- if(data || String(data)){
- this.appendChild(this.ownerDocument.createTextNode(data));
- }
- break;
- default:
- this.data = data;
- this.value = data;
- this.nodeValue = data;
- }
- }
- })
-
- function getTextContent(node){
- switch(node.nodeType){
- case ELEMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- var buf = [];
- node = node.firstChild;
- while(node){
- if(node.nodeType!==7 && node.nodeType !==8){
- buf.push(getTextContent(node));
- }
- node = node.nextSibling;
- }
- return buf.join('');
- default:
- return node.nodeValue;
- }
- }
- __set__ = function(object,key,value){
- //console.log(value)
- object['$$'+key] = value
- }
- }
- }catch(e){//ie8
- }
- //if(typeof require == 'function'){
- exports.DocumentType = DocumentType;
- exports.DOMException = DOMException;
- exports.DOMImplementation = DOMImplementation;
- exports.Element = Element;
- exports.Node = Node;
- exports.NodeList = NodeList;
- exports.XMLSerializer = XMLSerializer;
- //}
- /***/ }),
- /* 4 */
- /***/ (function(module, exports) {
- var initEvent = function (cos) {
- var listeners = {};
- var getList = function (action) {
- !listeners[action] && (listeners[action] = []);
- return listeners[action];
- };
- cos.on = function (action, callback) {
- if (action === 'task-list-update') {
- console.warn('warning: Event "' + action + '" has been deprecated. Please use "list-update" instead.');
- }
- getList(action).push(callback);
- };
- cos.off = function (action, callback) {
- var list = getList(action);
- for (var i = list.length - 1; i >= 0; i--) {
- callback === list[i] && list.splice(i, 1);
- }
- };
- cos.emit = function (action, data) {
- var list = getList(action).map(function (cb) {
- return cb;
- });
- for (var i = 0; i < list.length; i++) {
- list[i](data);
- }
- };
- };
- var EventProxy = function () {
- initEvent(this);
- };
- module.exports.init = initEvent;
- module.exports.EventProxy = EventProxy;
- /***/ }),
- /* 5 */
- /***/ (function(module, exports, __webpack_require__) {
- var util = __webpack_require__(0);
- // 按照文件特征值,缓存 UploadId
- var cacheKey = 'cos_sdk_upload_cache';
- var expires = 30 * 24 * 3600;
- var cache;
- var timer;
- var getCache = function () {
- try {
- var val = JSON.parse(localStorage.getItem(cacheKey));
- } catch (e) {}
- if (!val) val = [];
- cache = val;
- };
- var setCache = function () {
- try {
- localStorage.setItem(cacheKey, JSON.stringify(cache));
- } catch (e) {}
- };
- var init = function () {
- if (cache) return;
- getCache.call(this);
- // 清理太老旧的数据
- var changed = false;
- var now = Math.round(Date.now() / 1000);
- for (var i = cache.length - 1; i >= 0; i--) {
- var mtime = cache[i][2];
- if (!mtime || mtime + expires < now) {
- cache.splice(i, 1);
- changed = true;
- }
- }
- changed && setCache();
- };
- // 把缓存存到本地
- var save = function () {
- if (timer) return;
- timer = setTimeout(function () {
- setCache();
- timer = null;
- }, 400);
- };
- var mod = {
- using: {},
- // 标记 UploadId 正在使用
- setUsing: function (uuid) {
- mod.using[uuid] = true;
- },
- // 标记 UploadId 已经没在使用
- removeUsing: function (uuid) {
- delete mod.using[uuid];
- },
- // 用上传参数生成哈希值
- getFileId: function (file, ChunkSize, Bucket, Key) {
- if (file.name && file.size && file.lastModifiedDate && ChunkSize) {
- return util.md5([file.name, file.size, file.lastModifiedDate, ChunkSize, Bucket, Key].join('::'));
- } else {
- return null;
- }
- },
- // 获取文件对应的 UploadId 列表
- getUploadIdList: function (uuid) {
- if (!uuid) return null;
- init.call(this);
- var list = [];
- for (var i = 0; i < cache.length; i++) {
- if (cache[i][0] === uuid) list.push(cache[i][1]);
- }
- return list.length ? list : null;
- },
- // 缓存 UploadId
- saveUploadId: function (uuid, UploadId, limit) {
- init.call(this);
- if (!uuid) return;
- // 清理没用的 UploadId,js 文件没有 FilePath ,只清理相同记录
- for (var i = cache.length - 1; i >= 0; i--) {
- var item = cache[i];
- if (item[0] === uuid && item[1] === UploadId) {
- cache.splice(i, 1);
- }
- }
- cache.unshift([uuid, UploadId, Math.round(Date.now() / 1000)]);
- if (cache.length > limit) cache.splice(limit);
- save();
- },
- // UploadId 已用完,移除掉
- removeUploadId: function (UploadId) {
- init.call(this);
- delete mod.using[UploadId];
- for (var i = cache.length - 1; i >= 0; i--) {
- if (cache[i][1] === UploadId) cache.splice(i, 1);
- }
- save();
- }
- };
- module.exports = mod;
- /***/ }),
- /* 6 */
- /***/ (function(module, exports, __webpack_require__) {
- var COS = __webpack_require__(7);
- module.exports = COS;
- /***/ }),
- /* 7 */
- /***/ (function(module, exports, __webpack_require__) {
- "use strict";
- var util = __webpack_require__(0);
- var event = __webpack_require__(4);
- var task = __webpack_require__(18);
- var base = __webpack_require__(19);
- var advance = __webpack_require__(21);
- var defaultOptions = {
- AppId: '', // AppId 已废弃,请拼接到 Bucket 后传入,例如:test-1250000000
- SecretId: '',
- SecretKey: '',
- SecurityToken: '', // 使用临时密钥需要注意自行刷新 Token
- ChunkRetryTimes: 2,
- FileParallelLimit: 3,
- ChunkParallelLimit: 3,
- ChunkSize: 1024 * 1024,
- SliceSize: 1024 * 1024,
- CopyChunkParallelLimit: 20,
- CopyChunkSize: 1024 * 1024 * 10,
- CopySliceSize: 1024 * 1024 * 10,
- MaxPartNumber: 10000,
- ProgressInterval: 1000,
- Domain: '',
- ServiceDomain: '',
- Protocol: '',
- CompatibilityMode: false,
- ForcePathStyle: false,
- UseRawKey: false,
- Timeout: 0, // 单位毫秒,0 代表不设置超时时间
- CorrectClockSkew: true,
- SystemClockOffset: 0, // 单位毫秒,ms
- UploadCheckContentMd5: false,
- UploadQueueSize: 10000,
- UploadAddMetaMd5: false,
- UploadIdCacheLimit: 50,
- UseAccelerate: false,
- ForceSignHost: true // 默认将host加入签名计算,关闭后可能导致越权风险,建议保持为true
- };
- // 对外暴露的类
- var COS = function (options) {
- this.options = util.extend(util.clone(defaultOptions), options || {});
- this.options.FileParallelLimit = Math.max(1, this.options.FileParallelLimit);
- this.options.ChunkParallelLimit = Math.max(1, this.options.ChunkParallelLimit);
- this.options.ChunkRetryTimes = Math.max(0, this.options.ChunkRetryTimes);
- this.options.ChunkSize = Math.max(1024 * 1024, this.options.ChunkSize);
- this.options.CopyChunkParallelLimit = Math.max(1, this.options.CopyChunkParallelLimit);
- this.options.CopyChunkSize = Math.max(1024 * 1024, this.options.CopyChunkSize);
- this.options.CopySliceSize = Math.max(0, this.options.CopySliceSize);
- this.options.MaxPartNumber = Math.max(1024, Math.min(10000, this.options.MaxPartNumber));
- this.options.Timeout = Math.max(0, this.options.Timeout);
- if (this.options.AppId) {
- console.warn('warning: AppId has been deprecated, Please put it at the end of parameter Bucket(E.g: "test-1250000000").');
- }
- if (this.options.SecretId && this.options.SecretId.indexOf(' ') > -1) {
- console.error('error: SecretId格式错误,请检查');
- console.error('error: SecretId format is incorrect. Please check');
- }
- if (this.options.SecretKey && this.options.SecretKey.indexOf(' ') > -1) {
- console.error('error: SecretKey格式错误,请检查');
- console.error('error: SecretKey format is incorrect. Please check');
- }
- if (util.isNode()) {
- console.warn('warning: cos-js-sdk-v5 不支持 nodejs 环境使用,请改用 cos-nodejs-sdk-v5,参考文档: https://cloud.tencent.com/document/product/436/8629');
- 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');
- }
- event.init(this);
- task.init(this);
- };
- base.init(COS, task);
- advance.init(COS, task);
- COS.util = {
- md5: util.md5,
- xml2json: util.xml2json,
- json2xml: util.json2xml
- };
- COS.getAuthorization = util.getAuth;
- COS.version = '1.3.9';
- module.exports = COS;
- /***/ }),
- /* 8 */
- /***/ (function(module, exports, __webpack_require__) {
- /* WEBPACK VAR INJECTION */(function(process, global) {var __WEBPACK_AMD_DEFINE_RESULT__;/* https://github.com/emn178/js-md5 */
- (function () {
- 'use strict';
- var ERROR = 'input is invalid type';
- var WINDOW = typeof window === 'object';
- var root = WINDOW ? window : {};
- if (root.JS_MD5_NO_WINDOW) {
- WINDOW = false;
- }
- var WEB_WORKER = !WINDOW && typeof self === 'object';
- var NODE_JS = !root.JS_MD5_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
- if (NODE_JS) {
- root = global;
- } else if (WEB_WORKER) {
- root = self;
- }
- var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports;
- var AMD = "function" === 'function' && __webpack_require__(10);
- var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
- var HEX_CHARS = '0123456789abcdef'.split('');
- var EXTRA = [128, 32768, 8388608, -2147483648];
- var SHIFT = [0, 8, 16, 24];
- var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];
- var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
- var blocks = [],
- buffer8;
- if (ARRAY_BUFFER) {
- var buffer = new ArrayBuffer(68);
- buffer8 = new Uint8Array(buffer);
- blocks = new Uint32Array(buffer);
- }
- if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {
- Array.isArray = function (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
- };
- }
- if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
- ArrayBuffer.isView = function (obj) {
- return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
- };
- }
- /**
- * @method hex
- * @memberof md5
- * @description Output hash as hex string
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {String} Hex string
- * @example
- * md5.hex('The quick brown fox jumps over the lazy dog');
- * // equal to
- * md5('The quick brown fox jumps over the lazy dog');
- */
- /**
- * @method digest
- * @memberof md5
- * @description Output hash as bytes array
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {Array} Bytes array
- * @example
- * md5.digest('The quick brown fox jumps over the lazy dog');
- */
- /**
- * @method array
- * @memberof md5
- * @description Output hash as bytes array
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {Array} Bytes array
- * @example
- * md5.array('The quick brown fox jumps over the lazy dog');
- */
- /**
- * @method arrayBuffer
- * @memberof md5
- * @description Output hash as ArrayBuffer
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {ArrayBuffer} ArrayBuffer
- * @example
- * md5.arrayBuffer('The quick brown fox jumps over the lazy dog');
- */
- /**
- * @method buffer
- * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
- * @memberof md5
- * @description Output hash as ArrayBuffer
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {ArrayBuffer} ArrayBuffer
- * @example
- * md5.buffer('The quick brown fox jumps over the lazy dog');
- */
- /**
- * @method base64
- * @memberof md5
- * @description Output hash as base64 string
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {String} base64 string
- * @example
- * md5.base64('The quick brown fox jumps over the lazy dog');
- */
- var createOutputMethod = function (outputType) {
- return function (message, isBinStr) {
- return new Md5(true).update(message, isBinStr)[outputType]();
- };
- };
- /**
- * @method create
- * @memberof md5
- * @description Create Md5 object
- * @returns {Md5} Md5 object.
- * @example
- * var hash = md5.create();
- */
- /**
- * @method update
- * @memberof md5
- * @description Create and update Md5 object
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {Md5} Md5 object.
- * @example
- * var hash = md5.update('The quick brown fox jumps over the lazy dog');
- * // equal to
- * var hash = md5.create();
- * hash.update('The quick brown fox jumps over the lazy dog');
- */
- var createMethod = function () {
- var method = createOutputMethod('hex');
- if (NODE_JS) {
- method = nodeWrap(method);
- }
- method.getCtx = method.create = function () {
- return new Md5();
- };
- method.update = function (message) {
- return method.create().update(message);
- };
- for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
- var type = OUTPUT_TYPES[i];
- method[type] = createOutputMethod(type);
- }
- return method;
- };
- var nodeWrap = function (method) {
- var crypto = eval("require('crypto')");
- var Buffer = eval("require('buffer').Buffer");
- var nodeMethod = function (message) {
- if (typeof message === 'string') {
- return crypto.createHash('md5').update(message, 'utf8').digest('hex');
- } else {
- if (message === null || message === undefined) {
- throw ERROR;
- } else if (message.constructor === ArrayBuffer) {
- message = new Uint8Array(message);
- }
- }
- if (Array.isArray(message) || ArrayBuffer.isView(message) || message.constructor === Buffer) {
- return crypto.createHash('md5').update(new Buffer(message)).digest('hex');
- } else {
- return method(message);
- }
- };
- return nodeMethod;
- };
- /**
- * Md5 class
- * @class Md5
- * @description This is internal class.
- * @see {@link md5.create}
- */
- function Md5(sharedMemory) {
- if (sharedMemory) {
- 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;
- this.blocks = blocks;
- this.buffer8 = buffer8;
- } else {
- if (ARRAY_BUFFER) {
- var buffer = new ArrayBuffer(68);
- this.buffer8 = new Uint8Array(buffer);
- this.blocks = new Uint32Array(buffer);
- } else {
- this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
- }
- }
- this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;
- this.finalized = this.hashed = false;
- this.first = true;
- }
- /**
- * @method update
- * @memberof Md5
- * @instance
- * @description Update hash
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {Md5} Md5 object.
- * @see {@link md5.update}
- */
- Md5.prototype.update = function (message, isBinStr) {
- if (this.finalized) {
- return;
- }
- var code,
- index = 0,
- i,
- length = message.length,
- blocks = this.blocks;
- var buffer8 = this.buffer8;
- while (index < length) {
- if (this.hashed) {
- this.hashed = false;
- blocks[0] = blocks[16];
- 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;
- }
- if (ARRAY_BUFFER) {
- for (i = this.start; index < length && i < 64; ++index) {
- code = message.charCodeAt(index);
- if (isBinStr || code < 0x80) {
- buffer8[i++] = code;
- } else if (code < 0x800) {
- buffer8[i++] = 0xc0 | code >> 6;
- buffer8[i++] = 0x80 | code & 0x3f;
- } else if (code < 0xd800 || code >= 0xe000) {
- buffer8[i++] = 0xe0 | code >> 12;
- buffer8[i++] = 0x80 | code >> 6 & 0x3f;
- buffer8[i++] = 0x80 | code & 0x3f;
- } else {
- code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++index) & 0x3ff);
- buffer8[i++] = 0xf0 | code >> 18;
- buffer8[i++] = 0x80 | code >> 12 & 0x3f;
- buffer8[i++] = 0x80 | code >> 6 & 0x3f;
- buffer8[i++] = 0x80 | code & 0x3f;
- }
- }
- } else {
- for (i = this.start; index < length && i < 64; ++index) {
- code = message.charCodeAt(index);
- if (isBinStr || code < 0x80) {
- blocks[i >> 2] |= code << SHIFT[i++ & 3];
- } else if (code < 0x800) {
- blocks[i >> 2] |= (0xc0 | code >> 6) << SHIFT[i++ & 3];
- blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
- } else if (code < 0xd800 || code >= 0xe000) {
- blocks[i >> 2] |= (0xe0 | code >> 12) << SHIFT[i++ & 3];
- blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];
- blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
- } else {
- code = 0x10000 + ((code & 0x3ff) << 10 | message.charCodeAt(++index) & 0x3ff);
- blocks[i >> 2] |= (0xf0 | code >> 18) << SHIFT[i++ & 3];
- blocks[i >> 2] |= (0x80 | code >> 12 & 0x3f) << SHIFT[i++ & 3];
- blocks[i >> 2] |= (0x80 | code >> 6 & 0x3f) << SHIFT[i++ & 3];
- blocks[i >> 2] |= (0x80 | code & 0x3f) << SHIFT[i++ & 3];
- }
- }
- }
- this.lastByteIndex = i;
- this.bytes += i - this.start;
- if (i >= 64) {
- this.start = i - 64;
- this.hash();
- this.hashed = true;
- } else {
- this.start = i;
- }
- }
- if (this.bytes > 4294967295) {
- this.hBytes += this.bytes / 4294967296 << 0;
- this.bytes = this.bytes % 4294967296;
- }
- return this;
- };
- Md5.prototype.finalize = function () {
- if (this.finalized) {
- return;
- }
- this.finalized = true;
- var blocks = this.blocks,
- i = this.lastByteIndex;
- blocks[i >> 2] |= EXTRA[i & 3];
- if (i >= 56) {
- if (!this.hashed) {
- this.hash();
- }
- blocks[0] = blocks[16];
- 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;
- }
- blocks[14] = this.bytes << 3;
- blocks[15] = this.hBytes << 3 | this.bytes >>> 29;
- this.hash();
- };
- Md5.prototype.hash = function () {
- var a,
- b,
- c,
- d,
- bc,
- da,
- blocks = this.blocks;
- if (this.first) {
- a = blocks[0] - 680876937;
- a = (a << 7 | a >>> 25) - 271733879 << 0;
- d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;
- d = (d << 12 | d >>> 20) + a << 0;
- c = (-271733879 ^ d & (a ^ -271733879)) + blocks[2] - 1126478375;
- c = (c << 17 | c >>> 15) + d << 0;
- b = (a ^ c & (d ^ a)) + blocks[3] - 1316259209;
- b = (b << 22 | b >>> 10) + c << 0;
- } else {
- a = this.h0;
- b = this.h1;
- c = this.h2;
- d = this.h3;
- a += (d ^ b & (c ^ d)) + blocks[0] - 680876936;
- a = (a << 7 | a >>> 25) + b << 0;
- d += (c ^ a & (b ^ c)) + blocks[1] - 389564586;
- d = (d << 12 | d >>> 20) + a << 0;
- c += (b ^ d & (a ^ b)) + blocks[2] + 606105819;
- c = (c << 17 | c >>> 15) + d << 0;
- b += (a ^ c & (d ^ a)) + blocks[3] - 1044525330;
- b = (b << 22 | b >>> 10) + c << 0;
- }
- a += (d ^ b & (c ^ d)) + blocks[4] - 176418897;
- a = (a << 7 | a >>> 25) + b << 0;
- d += (c ^ a & (b ^ c)) + blocks[5] + 1200080426;
- d = (d << 12 | d >>> 20) + a << 0;
- c += (b ^ d & (a ^ b)) + blocks[6] - 1473231341;
- c = (c << 17 | c >>> 15) + d << 0;
- b += (a ^ c & (d ^ a)) + blocks[7] - 45705983;
- b = (b << 22 | b >>> 10) + c << 0;
- a += (d ^ b & (c ^ d)) + blocks[8] + 1770035416;
- a = (a << 7 | a >>> 25) + b << 0;
- d += (c ^ a & (b ^ c)) + blocks[9] - 1958414417;
- d = (d << 12 | d >>> 20) + a << 0;
- c += (b ^ d & (a ^ b)) + blocks[10] - 42063;
- c = (c << 17 | c >>> 15) + d << 0;
- b += (a ^ c & (d ^ a)) + blocks[11] - 1990404162;
- b = (b << 22 | b >>> 10) + c << 0;
- a += (d ^ b & (c ^ d)) + blocks[12] + 1804603682;
- a = (a << 7 | a >>> 25) + b << 0;
- d += (c ^ a & (b ^ c)) + blocks[13] - 40341101;
- d = (d << 12 | d >>> 20) + a << 0;
- c += (b ^ d & (a ^ b)) + blocks[14] - 1502002290;
- c = (c << 17 | c >>> 15) + d << 0;
- b += (a ^ c & (d ^ a)) + blocks[15] + 1236535329;
- b = (b << 22 | b >>> 10) + c << 0;
- a += (c ^ d & (b ^ c)) + blocks[1] - 165796510;
- a = (a << 5 | a >>> 27) + b << 0;
- d += (b ^ c & (a ^ b)) + blocks[6] - 1069501632;
- d = (d << 9 | d >>> 23) + a << 0;
- c += (a ^ b & (d ^ a)) + blocks[11] + 643717713;
- c = (c << 14 | c >>> 18) + d << 0;
- b += (d ^ a & (c ^ d)) + blocks[0] - 373897302;
- b = (b << 20 | b >>> 12) + c << 0;
- a += (c ^ d & (b ^ c)) + blocks[5] - 701558691;
- a = (a << 5 | a >>> 27) + b << 0;
- d += (b ^ c & (a ^ b)) + blocks[10] + 38016083;
- d = (d << 9 | d >>> 23) + a << 0;
- c += (a ^ b & (d ^ a)) + blocks[15] - 660478335;
- c = (c << 14 | c >>> 18) + d << 0;
- b += (d ^ a & (c ^ d)) + blocks[4] - 405537848;
- b = (b << 20 | b >>> 12) + c << 0;
- a += (c ^ d & (b ^ c)) + blocks[9] + 568446438;
- a = (a << 5 | a >>> 27) + b << 0;
- d += (b ^ c & (a ^ b)) + blocks[14] - 1019803690;
- d = (d << 9 | d >>> 23) + a << 0;
- c += (a ^ b & (d ^ a)) + blocks[3] - 187363961;
- c = (c << 14 | c >>> 18) + d << 0;
- b += (d ^ a & (c ^ d)) + blocks[8] + 1163531501;
- b = (b << 20 | b >>> 12) + c << 0;
- a += (c ^ d & (b ^ c)) + blocks[13] - 1444681467;
- a = (a << 5 | a >>> 27) + b << 0;
- d += (b ^ c & (a ^ b)) + blocks[2] - 51403784;
- d = (d << 9 | d >>> 23) + a << 0;
- c += (a ^ b & (d ^ a)) + blocks[7] + 1735328473;
- c = (c << 14 | c >>> 18) + d << 0;
- b += (d ^ a & (c ^ d)) + blocks[12] - 1926607734;
- b = (b << 20 | b >>> 12) + c << 0;
- bc = b ^ c;
- a += (bc ^ d) + blocks[5] - 378558;
- a = (a << 4 | a >>> 28) + b << 0;
- d += (bc ^ a) + blocks[8] - 2022574463;
- d = (d << 11 | d >>> 21) + a << 0;
- da = d ^ a;
- c += (da ^ b) + blocks[11] + 1839030562;
- c = (c << 16 | c >>> 16) + d << 0;
- b += (da ^ c) + blocks[14] - 35309556;
- b = (b << 23 | b >>> 9) + c << 0;
- bc = b ^ c;
- a += (bc ^ d) + blocks[1] - 1530992060;
- a = (a << 4 | a >>> 28) + b << 0;
- d += (bc ^ a) + blocks[4] + 1272893353;
- d = (d << 11 | d >>> 21) + a << 0;
- da = d ^ a;
- c += (da ^ b) + blocks[7] - 155497632;
- c = (c << 16 | c >>> 16) + d << 0;
- b += (da ^ c) + blocks[10] - 1094730640;
- b = (b << 23 | b >>> 9) + c << 0;
- bc = b ^ c;
- a += (bc ^ d) + blocks[13] + 681279174;
- a = (a << 4 | a >>> 28) + b << 0;
- d += (bc ^ a) + blocks[0] - 358537222;
- d = (d << 11 | d >>> 21) + a << 0;
- da = d ^ a;
- c += (da ^ b) + blocks[3] - 722521979;
- c = (c << 16 | c >>> 16) + d << 0;
- b += (da ^ c) + blocks[6] + 76029189;
- b = (b << 23 | b >>> 9) + c << 0;
- bc = b ^ c;
- a += (bc ^ d) + blocks[9] - 640364487;
- a = (a << 4 | a >>> 28) + b << 0;
- d += (bc ^ a) + blocks[12] - 421815835;
- d = (d << 11 | d >>> 21) + a << 0;
- da = d ^ a;
- c += (da ^ b) + blocks[15] + 530742520;
- c = (c << 16 | c >>> 16) + d << 0;
- b += (da ^ c) + blocks[2] - 995338651;
- b = (b << 23 | b >>> 9) + c << 0;
- a += (c ^ (b | ~d)) + blocks[0] - 198630844;
- a = (a << 6 | a >>> 26) + b << 0;
- d += (b ^ (a | ~c)) + blocks[7] + 1126891415;
- d = (d << 10 | d >>> 22) + a << 0;
- c += (a ^ (d | ~b)) + blocks[14] - 1416354905;
- c = (c << 15 | c >>> 17) + d << 0;
- b += (d ^ (c | ~a)) + blocks[5] - 57434055;
- b = (b << 21 | b >>> 11) + c << 0;
- a += (c ^ (b | ~d)) + blocks[12] + 1700485571;
- a = (a << 6 | a >>> 26) + b << 0;
- d += (b ^ (a | ~c)) + blocks[3] - 1894986606;
- d = (d << 10 | d >>> 22) + a << 0;
- c += (a ^ (d | ~b)) + blocks[10] - 1051523;
- c = (c << 15 | c >>> 17) + d << 0;
- b += (d ^ (c | ~a)) + blocks[1] - 2054922799;
- b = (b << 21 | b >>> 11) + c << 0;
- a += (c ^ (b | ~d)) + blocks[8] + 1873313359;
- a = (a << 6 | a >>> 26) + b << 0;
- d += (b ^ (a | ~c)) + blocks[15] - 30611744;
- d = (d << 10 | d >>> 22) + a << 0;
- c += (a ^ (d | ~b)) + blocks[6] - 1560198380;
- c = (c << 15 | c >>> 17) + d << 0;
- b += (d ^ (c | ~a)) + blocks[13] + 1309151649;
- b = (b << 21 | b >>> 11) + c << 0;
- a += (c ^ (b | ~d)) + blocks[4] - 145523070;
- a = (a << 6 | a >>> 26) + b << 0;
- d += (b ^ (a | ~c)) + blocks[11] - 1120210379;
- d = (d << 10 | d >>> 22) + a << 0;
- c += (a ^ (d | ~b)) + blocks[2] + 718787259;
- c = (c << 15 | c >>> 17) + d << 0;
- b += (d ^ (c | ~a)) + blocks[9] - 343485551;
- b = (b << 21 | b >>> 11) + c << 0;
- if (this.first) {
- this.h0 = a + 1732584193 << 0;
- this.h1 = b - 271733879 << 0;
- this.h2 = c - 1732584194 << 0;
- this.h3 = d + 271733878 << 0;
- this.first = false;
- } else {
- this.h0 = this.h0 + a << 0;
- this.h1 = this.h1 + b << 0;
- this.h2 = this.h2 + c << 0;
- this.h3 = this.h3 + d << 0;
- }
- };
- /**
- * @method hex
- * @memberof Md5
- * @instance
- * @description Output hash as hex string
- * @returns {String} Hex string
- * @see {@link md5.hex}
- * @example
- * hash.hex();
- */
- Md5.prototype.hex = function () {
- this.finalize();
- var h0 = this.h0,
- h1 = this.h1,
- h2 = this.h2,
- h3 = this.h3;
- 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];
- };
- /**
- * @method toString
- * @memberof Md5
- * @instance
- * @description Output hash as hex string
- * @returns {String} Hex string
- * @see {@link md5.hex}
- * @example
- * hash.toString();
- */
- Md5.prototype.toString = Md5.prototype.hex;
- /**
- * @method digest
- * @memberof Md5
- * @instance
- * @description Output hash as bytes array
- * @returns {Array} Bytes array
- * @see {@link md5.digest}
- * @example
- * hash.digest();
- */
- Md5.prototype.digest = function (format) {
- if (format === 'hex') return this.hex();
- this.finalize();
- var h0 = this.h0,
- h1 = this.h1,
- h2 = this.h2,
- h3 = this.h3;
- 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];
- return res;
- };
- /**
- * @method array
- * @memberof Md5
- * @instance
- * @description Output hash as bytes array
- * @returns {Array} Bytes array
- * @see {@link md5.array}
- * @example
- * hash.array();
- */
- Md5.prototype.array = Md5.prototype.digest;
- /**
- * @method arrayBuffer
- * @memberof Md5
- * @instance
- * @description Output hash as ArrayBuffer
- * @returns {ArrayBuffer} ArrayBuffer
- * @see {@link md5.arrayBuffer}
- * @example
- * hash.arrayBuffer();
- */
- Md5.prototype.arrayBuffer = function () {
- this.finalize();
- var buffer = new ArrayBuffer(16);
- var blocks = new Uint32Array(buffer);
- blocks[0] = this.h0;
- blocks[1] = this.h1;
- blocks[2] = this.h2;
- blocks[3] = this.h3;
- return buffer;
- };
- /**
- * @method buffer
- * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
- * @memberof Md5
- * @instance
- * @description Output hash as ArrayBuffer
- * @returns {ArrayBuffer} ArrayBuffer
- * @see {@link md5.buffer}
- * @example
- * hash.buffer();
- */
- Md5.prototype.buffer = Md5.prototype.arrayBuffer;
- /**
- * @method base64
- * @memberof Md5
- * @instance
- * @description Output hash as base64 string
- * @returns {String} base64 string
- * @see {@link md5.base64}
- * @example
- * hash.base64();
- */
- Md5.prototype.base64 = function () {
- var v1,
- v2,
- v3,
- base64Str = '',
- bytes = this.array();
- for (var i = 0; i < 15;) {
- v1 = bytes[i++];
- v2 = bytes[i++];
- v3 = bytes[i++];
- 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];
- }
- v1 = bytes[i];
- base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] + BASE64_ENCODE_CHAR[v1 << 4 & 63] + '==';
- return base64Str;
- };
- var exports = createMethod();
- if (COMMON_JS) {
- module.exports = exports;
- } else {
- /**
- * @method md5
- * @description Md5 hash function, export to global in browsers.
- * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash
- * @returns {String} md5 hashes
- * @example
- * md5(''); // d41d8cd98f00b204e9800998ecf8427e
- * md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6
- * md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0
- *
- * // It also supports UTF-8 encoding
- * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07
- *
- * // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`
- * md5([]); // d41d8cd98f00b204e9800998ecf8427e
- * md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e
- */
- root.md5 = exports;
- if (AMD) {
- !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
- return exports;
- }).call(exports, __webpack_require__, exports, module),
- __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- }
- }
- })();
- /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2), __webpack_require__(9)))
- /***/ }),
- /* 9 */
- /***/ (function(module, exports) {
- var g;
- // This works in non-strict mode
- g = (function() {
- return this;
- })();
- try {
- // This works if eval is allowed (see CSP)
- g = g || Function("return this")() || (1,eval)("this");
- } catch(e) {
- // This works if the window reference is available
- if(typeof window === "object")
- g = window;
- }
- // g can still be undefined, but nothing to do about it...
- // We return undefined, instead of nothing here, so it's
- // easier to handle this case. if(!global) { ...}
- module.exports = g;
- /***/ }),
- /* 10 */
- /***/ (function(module, exports) {
- /* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals __webpack_amd_options__ */
- module.exports = __webpack_amd_options__;
- /* WEBPACK VAR INJECTION */}.call(exports, {}))
- /***/ }),
- /* 11 */
- /***/ (function(module, exports, __webpack_require__) {
- /*
- CryptoJS v3.1.2
- code.google.com/p/crypto-js
- (c) 2009-2013 by Jeff Mott. All rights reserved.
- code.google.com/p/crypto-js/wiki/License
- */
- var CryptoJS = CryptoJS || function (g, l) {
- var e = {},
- d = e.lib = {},
- m = function () {},
- k = d.Base = { extend: function (a) {
- m.prototype = this;var c = new m();a && c.mixIn(a);c.hasOwnProperty("init") || (c.init = function () {
- c.$super.init.apply(this, arguments);
- });c.init.prototype = c;c.$super = this;return c;
- }, create: function () {
- var a = this.extend();a.init.apply(a, arguments);return a;
- }, init: function () {}, mixIn: function (a) {
- for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]);a.hasOwnProperty("toString") && (this.toString = a.toString);
- }, clone: function () {
- return this.init.prototype.extend(this);
- } },
- p = d.WordArray = k.extend({ init: function (a, c) {
- a = this.words = a || [];this.sigBytes = c != l ? c : 4 * a.length;
- }, toString: function (a) {
- return (a || n).stringify(this);
- }, concat: function (a) {
- var c = this.words,
- q = a.words,
- 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;
- }, clamp: function () {
- var a = this.words,
- c = this.sigBytes;a[c >>> 2] &= 4294967295 << 32 - 8 * (c % 4);a.length = g.ceil(c / 4);
- }, clone: function () {
- var a = k.clone.call(this);a.words = this.words.slice(0);return a;
- }, random: function (a) {
- for (var c = [], b = 0; b < a; b += 4) c.push(4294967296 * g.random() | 0);return new p.init(c, a);
- } }),
- b = e.enc = {},
- n = b.Hex = { stringify: function (a) {
- var c = a.words;a = a.sigBytes;for (var b = [], f = 0; f < a; f++) {
- var d = c[f >>> 2] >>> 24 - 8 * (f % 4) & 255;b.push((d >>> 4).toString(16));b.push((d & 15).toString(16));
- }return b.join("");
- }, parse: function (a) {
- 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);
- } },
- j = b.Latin1 = { stringify: function (a) {
- 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("");
- }, parse: function (a) {
- 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);
- } },
- h = b.Utf8 = { stringify: function (a) {
- try {
- return decodeURIComponent(escape(j.stringify(a)));
- } catch (c) {
- throw Error("Malformed UTF-8 data");
- }
- }, parse: function (a) {
- return j.parse(unescape(encodeURIComponent(a)));
- } },
- r = d.BufferedBlockAlgorithm = k.extend({ reset: function () {
- this._data = new p.init();this._nDataBytes = 0;
- }, _append: function (a) {
- "string" == typeof a && (a = h.parse(a));this._data.concat(a);this._nDataBytes += a.sigBytes;
- }, _process: function (a) {
- var c = this._data,
- b = c.words,
- f = c.sigBytes,
- d = this.blockSize,
- e = f / (4 * d),
- e = a ? g.ceil(e) : g.max((e | 0) - this._minBufferSize, 0);a = e * d;f = g.min(4 * a, f);if (a) {
- for (var k = 0; k < a; k += d) this._doProcessBlock(b, k);k = b.splice(0, a);c.sigBytes -= f;
- }return new p.init(k, f);
- }, clone: function () {
- var a = k.clone.call(this);
- a._data = this._data.clone();return a;
- }, _minBufferSize: 0 });d.Hasher = r.extend({ cfg: k.extend(), init: function (a) {
- this.cfg = this.cfg.extend(a);this.reset();
- }, reset: function () {
- r.reset.call(this);this._doReset();
- }, update: function (a) {
- this._append(a);this._process();return this;
- }, finalize: function (a) {
- a && this._append(a);return this._doFinalize();
- }, blockSize: 16, _createHelper: function (a) {
- return function (b, d) {
- return new a.init(d).finalize(b);
- };
- }, _createHmacHelper: function (a) {
- return function (b, d) {
- return new s.HMAC.init(a, d).finalize(b);
- };
- } });var s = e.algo = {};return e;
- }(Math);
- (function () {
- var g = CryptoJS,
- l = g.lib,
- e = l.WordArray,
- d = l.Hasher,
- m = [],
- l = g.algo.SHA1 = d.extend({ _doReset: function () {
- this._hash = new e.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]);
- }, _doProcessBlock: function (d, e) {
- 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++) {
- if (16 > a) m[a] = d[e + a] | 0;else {
- var c = m[a - 3] ^ m[a - 8] ^ m[a - 14] ^ m[a - 16];m[a] = c << 1 | c >>> 31;
- }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;
- }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;
- }, _doFinalize: function () {
- var d = this._data,
- e = d.words,
- b = 8 * this._nDataBytes,
- 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;
- }, clone: function () {
- var e = d.clone.call(this);e._hash = this._hash.clone();return e;
- } });g.SHA1 = d._createHelper(l);g.HmacSHA1 = d._createHmacHelper(l);
- })();
- (function () {
- var g = CryptoJS,
- l = g.enc.Utf8;g.algo.HMAC = g.lib.Base.extend({ init: function (e, d) {
- e = this._hasher = new e.init();"string" == typeof d && (d = l.parse(d));var g = e.blockSize,
- 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();
- }, reset: function () {
- var e = this._hasher;e.reset();e.update(this._iKey);
- }, update: function (e) {
- this._hasher.update(e);return this;
- }, finalize: function (e) {
- var d = this._hasher;e = d.finalize(e);d.reset();return d.finalize(this._oKey.clone().concat(e));
- } });
- })();
- (function () {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var WordArray = C_lib.WordArray;
- var C_enc = C.enc;
- /**
- * Base64 encoding strategy.
- */
- var Base64 = C_enc.Base64 = {
- /**
- * Converts a word array to a Base64 string.
- *
- * @param {WordArray} wordArray The word array.
- *
- * @return {string} The Base64 string.
- *
- * @static
- *
- * @example
- *
- * var base64String = CryptoJS.enc.Base64.stringify(wordArray);
- */
- stringify: function (wordArray) {
- // Shortcuts
- var words = wordArray.words;
- var sigBytes = wordArray.sigBytes;
- var map = this._map;
- // Clamp excess bits
- wordArray.clamp();
- // Convert
- var base64Chars = [];
- for (var i = 0; i < sigBytes; i += 3) {
- var byte1 = words[i >>> 2] >>> 24 - i % 4 * 8 & 0xff;
- var byte2 = words[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 0xff;
- var byte3 = words[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 0xff;
- var triplet = byte1 << 16 | byte2 << 8 | byte3;
- for (var j = 0; j < 4 && i + j * 0.75 < sigBytes; j++) {
- base64Chars.push(map.charAt(triplet >>> 6 * (3 - j) & 0x3f));
- }
- }
- // Add padding
- var paddingChar = map.charAt(64);
- if (paddingChar) {
- while (base64Chars.length % 4) {
- base64Chars.push(paddingChar);
- }
- }
- return base64Chars.join('');
- },
- /**
- * Converts a Base64 string to a word array.
- *
- * @param {string} base64Str The Base64 string.
- *
- * @return {WordArray} The word array.
- *
- * @static
- *
- * @example
- *
- * var wordArray = CryptoJS.enc.Base64.parse(base64String);
- */
- parse: function (base64Str) {
- // Shortcuts
- var base64StrLength = base64Str.length;
- var map = this._map;
- // Ignore padding
- var paddingChar = map.charAt(64);
- if (paddingChar) {
- var paddingIndex = base64Str.indexOf(paddingChar);
- if (paddingIndex != -1) {
- base64StrLength = paddingIndex;
- }
- }
- // Convert
- var words = [];
- var nBytes = 0;
- for (var i = 0; i < base64StrLength; i++) {
- if (i % 4) {
- var bits1 = map.indexOf(base64Str.charAt(i - 1)) << i % 4 * 2;
- var bits2 = map.indexOf(base64Str.charAt(i)) >>> 6 - i % 4 * 2;
- words[nBytes >>> 2] |= (bits1 | bits2) << 24 - nBytes % 4 * 8;
- nBytes++;
- }
- }
- return WordArray.create(words, nBytes);
- },
- _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
- };
- })();
- if (true) {
- module.exports = CryptoJS;
- } else {
- window.CryptoJS = CryptoJS;
- }
- /***/ }),
- /* 12 */
- /***/ (function(module, exports, __webpack_require__) {
- /* Copyright 2015 William Summers, MetaTribal LLC
- * adapted from https://developer.mozilla.org/en-US/docs/JXON
- *
- * Licensed under the MIT License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/MIT
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /**
- * @author William Summers
- * https://github.com/metatribal/xmlToJSON
- */
- var DOMParser = __webpack_require__(13).DOMParser;
- var xmlToJSON = function () {
- this.version = "1.3.5";
- var options = { // set up the default options
- mergeCDATA: true, // extract cdata and merge with text
- normalize: true, // collapse multiple spaces to single space
- stripElemPrefix: true // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property
- };
- var prefixMatch = new RegExp(/(?!xmlns)^.*:/);
- var trimMatch = new RegExp(/^\s+|\s+$/g);
- this.grokType = function (sValue) {
- if (/^\s*$/.test(sValue)) {
- return null;
- }
- if (/^(?:true|false)$/i.test(sValue)) {
- return sValue.toLowerCase() === "true";
- }
- if (isFinite(sValue)) {
- return parseFloat(sValue);
- }
- return sValue;
- };
- this.parseString = function (xmlString, opt) {
- if (xmlString) {
- var xml = this.stringToXML(xmlString);
- if (xml.getElementsByTagName('parsererror').length) {
- return null;
- } else {
- return this.parseXML(xml, opt);
- }
- } else {
- return null;
- }
- };
- this.parseXML = function (oXMLParent, opt) {
- // initialize options
- for (var key in opt) {
- options[key] = opt[key];
- }
- var vResult = {},
- nLength = 0,
- sCollectedTxt = "";
- // iterate over the children
- var childNum = oXMLParent.childNodes.length;
- if (childNum) {
- for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) {
- oNode = oXMLParent.childNodes.item(nItem);
- if (oNode.nodeType === 4) {
- if (options.mergeCDATA) {
- sCollectedTxt += oNode.nodeValue;
- }
- } /* nodeType is "CDATASection" (4) */
- else if (oNode.nodeType === 3) {
- sCollectedTxt += oNode.nodeValue;
- } /* nodeType is "Text" (3) */
- else if (oNode.nodeType === 1) {
- /* nodeType is "Element" (1) */
- if (nLength === 0) {
- vResult = {};
- }
- // using nodeName to support browser (IE) implementation with no 'localName' property
- if (options.stripElemPrefix) {
- sProp = oNode.nodeName.replace(prefixMatch, '');
- } else {
- sProp = oNode.nodeName;
- }
- vContent = xmlToJSON.parseXML(oNode);
- if (vResult.hasOwnProperty(sProp)) {
- if (vResult[sProp].constructor !== Array) {
- vResult[sProp] = [vResult[sProp]];
- }
- vResult[sProp].push(vContent);
- } else {
- vResult[sProp] = vContent;
- nLength++;
- }
- }
- }
- }
- if (!Object.keys(vResult).length) {
- // vResult = sCollectedTxt.replace(trimMatch, '') || ''; // by carsonxu 修复 getBucket返回的 Key 是 " /" 这种场景
- vResult = sCollectedTxt || '';
- }
- return vResult;
- };
- // Convert xmlDocument to a string
- // Returns null on failure
- this.xmlToString = function (xmlDoc) {
- try {
- var xmlString = xmlDoc.xml ? xmlDoc.xml : new XMLSerializer().serializeToString(xmlDoc);
- return xmlString;
- } catch (err) {
- return null;
- }
- };
- // Convert a string to XML Node Structure
- // Returns null on failure
- this.stringToXML = function (xmlString) {
- try {
- var xmlDoc = null;
- if (window.DOMParser) {
- var parser = new DOMParser();
- xmlDoc = parser.parseFromString(xmlString, "text/xml");
- return xmlDoc;
- } else {
- xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
- xmlDoc.async = false;
- xmlDoc.loadXML(xmlString);
- return xmlDoc;
- }
- } catch (e) {
- return null;
- }
- };
- return this;
- }.call({});
- var xml2json = function (xmlString) {
- return xmlToJSON.parseString(xmlString);
- };
- module.exports = xml2json;
- /***/ }),
- /* 13 */
- /***/ (function(module, exports, __webpack_require__) {
- var dom = __webpack_require__(3)
- exports.DOMImplementation = dom.DOMImplementation
- exports.XMLSerializer = dom.XMLSerializer
- exports.DOMParser = __webpack_require__(14).DOMParser
- /***/ }),
- /* 14 */
- /***/ (function(module, exports, __webpack_require__) {
- var conventions = __webpack_require__(1);
- var dom = __webpack_require__(3)
- var entities = __webpack_require__(15);
- var sax = __webpack_require__(16);
- var DOMImplementation = dom.DOMImplementation;
- var NAMESPACE = conventions.NAMESPACE;
- var ParseError = sax.ParseError;
- var XMLReader = sax.XMLReader;
- /**
- * Normalizes line ending according to https://www.w3.org/TR/xml11/#sec-line-ends:
- *
- * > XML parsed entities are often stored in computer files which,
- * > for editing convenience, are organized into lines.
- * > These lines are typically separated by some combination
- * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA).
- * >
- * > To simplify the tasks of applications, the XML processor must behave
- * > as if it normalized all line breaks in external parsed entities (including the document entity)
- * > on input, before parsing, by translating all of the following to a single #xA character:
- * >
- * > 1. the two-character sequence #xD #xA
- * > 2. the two-character sequence #xD #x85
- * > 3. the single character #x85
- * > 4. the single character #x2028
- * > 5. any #xD character that is not immediately followed by #xA or #x85.
- *
- * @param {string} input
- * @returns {string}
- */
- function normalizeLineEndings(input) {
- return input
- .replace(/\r[\n\u0085]/g, '\n')
- .replace(/[\r\u0085\u2028]/g, '\n')
- }
- /**
- * @typedef Locator
- * @property {number} [columnNumber]
- * @property {number} [lineNumber]
- */
- /**
- * @typedef DOMParserOptions
- * @property {DOMHandler} [domBuilder]
- * @property {Function} [errorHandler]
- * @property {(string) => string} [normalizeLineEndings] used to replace line endings before parsing
- * defaults to `normalizeLineEndings`
- * @property {Locator} [locator]
- * @property {Record<string, string>} [xmlns]
- *
- * @see normalizeLineEndings
- */
- /**
- * The DOMParser interface provides the ability to parse XML or HTML source code
- * from a string into a DOM `Document`.
- *
- * _xmldom is different from the spec in that it allows an `options` parameter,
- * to override the default behavior._
- *
- * @param {DOMParserOptions} [options]
- * @constructor
- *
- * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
- * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization
- */
- function DOMParser(options){
- this.options = options ||{locator:{}};
- }
- DOMParser.prototype.parseFromString = function(source,mimeType){
- var options = this.options;
- var sax = new XMLReader();
- var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
- var errorHandler = options.errorHandler;
- var locator = options.locator;
- var defaultNSMap = options.xmlns||{};
- var isHTML = /\/x?html?$/.test(mimeType);//mimeType.toLowerCase().indexOf('html') > -1;
- var entityMap = isHTML ? entities.HTML_ENTITIES : entities.XML_ENTITIES;
- if(locator){
- domBuilder.setDocumentLocator(locator)
- }
- sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
- sax.domBuilder = options.domBuilder || domBuilder;
- if(isHTML){
- defaultNSMap[''] = NAMESPACE.HTML;
- }
- defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML;
- var normalize = options.normalizeLineEndings || normalizeLineEndings;
- if (source && typeof source === 'string') {
- sax.parse(
- normalize(source),
- defaultNSMap,
- entityMap
- )
- } else {
- sax.errorHandler.error('invalid doc source')
- }
- return domBuilder.doc;
- }
- function buildErrorHandler(errorImpl,domBuilder,locator){
- if(!errorImpl){
- if(domBuilder instanceof DOMHandler){
- return domBuilder;
- }
- errorImpl = domBuilder ;
- }
- var errorHandler = {}
- var isCallback = errorImpl instanceof Function;
- locator = locator||{}
- function build(key){
- var fn = errorImpl[key];
- if(!fn && isCallback){
- fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
- }
- errorHandler[key] = fn && function(msg){
- fn('[xmldom '+key+']\t'+msg+_locator(locator));
- }||function(){};
- }
- build('warning');
- build('error');
- build('fatalError');
- return errorHandler;
- }
- //console.log('#\n\n\n\n\n\n\n####')
- /**
- * +ContentHandler+ErrorHandler
- * +LexicalHandler+EntityResolver2
- * -DeclHandler-DTDHandler
- *
- * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
- * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
- * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
- */
- function DOMHandler() {
- this.cdata = false;
- }
- function position(locator,node){
- node.lineNumber = locator.lineNumber;
- node.columnNumber = locator.columnNumber;
- }
- /**
- * @see org.xml.sax.ContentHandler#startDocument
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
- */
- DOMHandler.prototype = {
- startDocument : function() {
- this.doc = new DOMImplementation().createDocument(null, null, null);
- if (this.locator) {
- this.doc.documentURI = this.locator.systemId;
- }
- },
- startElement:function(namespaceURI, localName, qName, attrs) {
- var doc = this.doc;
- var el = doc.createElementNS(namespaceURI, qName||localName);
- var len = attrs.length;
- appendElement(this, el);
- this.currentElement = el;
- this.locator && position(this.locator,el)
- for (var i = 0 ; i < len; i++) {
- var namespaceURI = attrs.getURI(i);
- var value = attrs.getValue(i);
- var qName = attrs.getQName(i);
- var attr = doc.createAttributeNS(namespaceURI, qName);
- this.locator &&position(attrs.getLocator(i),attr);
- attr.value = attr.nodeValue = value;
- el.setAttributeNode(attr)
- }
- },
- endElement:function(namespaceURI, localName, qName) {
- var current = this.currentElement
- var tagName = current.tagName;
- this.currentElement = current.parentNode;
- },
- startPrefixMapping:function(prefix, uri) {
- },
- endPrefixMapping:function(prefix) {
- },
- processingInstruction:function(target, data) {
- var ins = this.doc.createProcessingInstruction(target, data);
- this.locator && position(this.locator,ins)
- appendElement(this, ins);
- },
- ignorableWhitespace:function(ch, start, length) {
- },
- characters:function(chars, start, length) {
- chars = _toString.apply(this,arguments)
- //console.log(chars)
- if(chars){
- if (this.cdata) {
- var charNode = this.doc.createCDATASection(chars);
- } else {
- var charNode = this.doc.createTextNode(chars);
- }
- if(this.currentElement){
- this.currentElement.appendChild(charNode);
- }else if(/^\s*$/.test(chars)){
- this.doc.appendChild(charNode);
- //process xml
- }
- this.locator && position(this.locator,charNode)
- }
- },
- skippedEntity:function(name) {
- },
- endDocument:function() {
- this.doc.normalize();
- },
- setDocumentLocator:function (locator) {
- if(this.locator = locator){// && !('lineNumber' in locator)){
- locator.lineNumber = 0;
- }
- },
- //LexicalHandler
- comment:function(chars, start, length) {
- chars = _toString.apply(this,arguments)
- var comm = this.doc.createComment(chars);
- this.locator && position(this.locator,comm)
- appendElement(this, comm);
- },
- startCDATA:function() {
- //used in characters() methods
- this.cdata = true;
- },
- endCDATA:function() {
- this.cdata = false;
- },
- startDTD:function(name, publicId, systemId) {
- var impl = this.doc.implementation;
- if (impl && impl.createDocumentType) {
- var dt = impl.createDocumentType(name, publicId, systemId);
- this.locator && position(this.locator,dt)
- appendElement(this, dt);
- this.doc.doctype = dt;
- }
- },
- /**
- * @see org.xml.sax.ErrorHandler
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
- */
- warning:function(error) {
- console.warn('[xmldom warning]\t'+error,_locator(this.locator));
- },
- error:function(error) {
- console.error('[xmldom error]\t'+error,_locator(this.locator));
- },
- fatalError:function(error) {
- throw new ParseError(error, this.locator);
- }
- }
- function _locator(l){
- if(l){
- return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
- }
- }
- function _toString(chars,start,length){
- if(typeof chars == 'string'){
- return chars.substr(start,length)
- }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
- if(chars.length >= start+length || start){
- return new java.lang.String(chars,start,length)+'';
- }
- return chars;
- }
- }
- /*
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
- * used method of org.xml.sax.ext.LexicalHandler:
- * #comment(chars, start, length)
- * #startCDATA()
- * #endCDATA()
- * #startDTD(name, publicId, systemId)
- *
- *
- * IGNORED method of org.xml.sax.ext.LexicalHandler:
- * #endDTD()
- * #startEntity(name)
- * #endEntity(name)
- *
- *
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
- * IGNORED method of org.xml.sax.ext.DeclHandler
- * #attributeDecl(eName, aName, type, mode, value)
- * #elementDecl(name, model)
- * #externalEntityDecl(name, publicId, systemId)
- * #internalEntityDecl(name, value)
- * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
- * IGNORED method of org.xml.sax.EntityResolver2
- * #resolveEntity(String name,String publicId,String baseURI,String systemId)
- * #resolveEntity(publicId, systemId)
- * #getExternalSubset(name, baseURI)
- * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
- * IGNORED method of org.xml.sax.DTDHandler
- * #notationDecl(name, publicId, systemId) {};
- * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
- */
- "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
- DOMHandler.prototype[key] = function(){return null}
- })
- /* 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 */
- function appendElement (hander,node) {
- if (!hander.currentElement) {
- hander.doc.appendChild(node);
- } else {
- hander.currentElement.appendChild(node);
- }
- }//appendChild and setAttributeNS are preformance key
- exports.__DOMHandler = DOMHandler;
- exports.normalizeLineEndings = normalizeLineEndings;
- exports.DOMParser = DOMParser;
- /***/ }),
- /* 15 */
- /***/ (function(module, exports, __webpack_require__) {
- var freeze = __webpack_require__(1).freeze;
- /**
- * The entities that are predefined in every XML document.
- *
- * @see https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-predefined-ent W3C XML 1.1
- * @see https://www.w3.org/TR/2008/REC-xml-20081126/#sec-predefined-ent W3C XML 1.0
- * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML Wikipedia
- */
- exports.XML_ENTITIES = freeze({amp:'&', apos:"'", gt:'>', lt:'<', quot:'"'})
- /**
- * A map of currently 241 entities that are detected in an HTML document.
- * They contain all entries from `XML_ENTITIES`.
- *
- * @see XML_ENTITIES
- * @see DOMParser.parseFromString
- * @see DOMImplementation.prototype.createHTMLDocument
- * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5) Spec
- * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names
- * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML
- * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML Wikipedia (HTML)
- * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML Wikpedia (XHTML)
- */
- exports.HTML_ENTITIES = freeze({
- lt: '<',
- gt: '>',
- amp: '&',
- quot: '"',
- apos: "'",
- Agrave: "À",
- Aacute: "Á",
- Acirc: "Â",
- Atilde: "Ã",
- Auml: "Ä",
- Aring: "Å",
- AElig: "Æ",
- Ccedil: "Ç",
- Egrave: "È",
- Eacute: "É",
- Ecirc: "Ê",
- Euml: "Ë",
- Igrave: "Ì",
- Iacute: "Í",
- Icirc: "Î",
- Iuml: "Ï",
- ETH: "Ð",
- Ntilde: "Ñ",
- Ograve: "Ò",
- Oacute: "Ó",
- Ocirc: "Ô",
- Otilde: "Õ",
- Ouml: "Ö",
- Oslash: "Ø",
- Ugrave: "Ù",
- Uacute: "Ú",
- Ucirc: "Û",
- Uuml: "Ü",
- Yacute: "Ý",
- THORN: "Þ",
- szlig: "ß",
- agrave: "à",
- aacute: "á",
- acirc: "â",
- atilde: "ã",
- auml: "ä",
- aring: "å",
- aelig: "æ",
- ccedil: "ç",
- egrave: "è",
- eacute: "é",
- ecirc: "ê",
- euml: "ë",
- igrave: "ì",
- iacute: "í",
- icirc: "î",
- iuml: "ï",
- eth: "ð",
- ntilde: "ñ",
- ograve: "ò",
- oacute: "ó",
- ocirc: "ô",
- otilde: "õ",
- ouml: "ö",
- oslash: "ø",
- ugrave: "ù",
- uacute: "ú",
- ucirc: "û",
- uuml: "ü",
- yacute: "ý",
- thorn: "þ",
- yuml: "ÿ",
- nbsp: "\u00a0",
- iexcl: "¡",
- cent: "¢",
- pound: "£",
- curren: "¤",
- yen: "¥",
- brvbar: "¦",
- sect: "§",
- uml: "¨",
- copy: "©",
- ordf: "ª",
- laquo: "«",
- not: "¬",
- shy: "",
- reg: "®",
- macr: "¯",
- deg: "°",
- plusmn: "±",
- sup2: "²",
- sup3: "³",
- acute: "´",
- micro: "µ",
- para: "¶",
- middot: "·",
- cedil: "¸",
- sup1: "¹",
- ordm: "º",
- raquo: "»",
- frac14: "¼",
- frac12: "½",
- frac34: "¾",
- iquest: "¿",
- times: "×",
- divide: "÷",
- forall: "∀",
- part: "∂",
- exist: "∃",
- empty: "∅",
- nabla: "∇",
- isin: "∈",
- notin: "∉",
- ni: "∋",
- prod: "∏",
- sum: "∑",
- minus: "−",
- lowast: "∗",
- radic: "√",
- prop: "∝",
- infin: "∞",
- ang: "∠",
- and: "∧",
- or: "∨",
- cap: "∩",
- cup: "∪",
- 'int': "∫",
- there4: "∴",
- sim: "∼",
- cong: "≅",
- asymp: "≈",
- ne: "≠",
- equiv: "≡",
- le: "≤",
- ge: "≥",
- sub: "⊂",
- sup: "⊃",
- nsub: "⊄",
- sube: "⊆",
- supe: "⊇",
- oplus: "⊕",
- otimes: "⊗",
- perp: "⊥",
- sdot: "⋅",
- Alpha: "Α",
- Beta: "Β",
- Gamma: "Γ",
- Delta: "Δ",
- Epsilon: "Ε",
- Zeta: "Ζ",
- Eta: "Η",
- Theta: "Θ",
- Iota: "Ι",
- Kappa: "Κ",
- Lambda: "Λ",
- Mu: "Μ",
- Nu: "Ν",
- Xi: "Ξ",
- Omicron: "Ο",
- Pi: "Π",
- Rho: "Ρ",
- Sigma: "Σ",
- Tau: "Τ",
- Upsilon: "Υ",
- Phi: "Φ",
- Chi: "Χ",
- Psi: "Ψ",
- Omega: "Ω",
- alpha: "α",
- beta: "β",
- gamma: "γ",
- delta: "δ",
- epsilon: "ε",
- zeta: "ζ",
- eta: "η",
- theta: "θ",
- iota: "ι",
- kappa: "κ",
- lambda: "λ",
- mu: "μ",
- nu: "ν",
- xi: "ξ",
- omicron: "ο",
- pi: "π",
- rho: "ρ",
- sigmaf: "ς",
- sigma: "σ",
- tau: "τ",
- upsilon: "υ",
- phi: "φ",
- chi: "χ",
- psi: "ψ",
- omega: "ω",
- thetasym: "ϑ",
- upsih: "ϒ",
- piv: "ϖ",
- OElig: "Œ",
- oelig: "œ",
- Scaron: "Š",
- scaron: "š",
- Yuml: "Ÿ",
- fnof: "ƒ",
- circ: "ˆ",
- tilde: "˜",
- ensp: " ",
- emsp: " ",
- thinsp: " ",
- zwnj: "",
- zwj: "",
- lrm: "",
- rlm: "",
- ndash: "–",
- mdash: "—",
- lsquo: "‘",
- rsquo: "’",
- sbquo: "‚",
- ldquo: "“",
- rdquo: "”",
- bdquo: "„",
- dagger: "†",
- Dagger: "‡",
- bull: "•",
- hellip: "…",
- permil: "‰",
- prime: "′",
- Prime: "″",
- lsaquo: "‹",
- rsaquo: "›",
- oline: "‾",
- euro: "€",
- trade: "™",
- larr: "←",
- uarr: "↑",
- rarr: "→",
- darr: "↓",
- harr: "↔",
- crarr: "↵",
- lceil: "⌈",
- rceil: "⌉",
- lfloor: "⌊",
- rfloor: "⌋",
- loz: "◊",
- spades: "♠",
- clubs: "♣",
- hearts: "♥",
- diams: "♦"
- });
- /**
- * @deprecated use `HTML_ENTITIES` instead
- * @see HTML_ENTITIES
- */
- exports.entityMap = exports.HTML_ENTITIES
- /***/ }),
- /* 16 */
- /***/ (function(module, exports, __webpack_require__) {
- var NAMESPACE = __webpack_require__(1).NAMESPACE;
- //[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]
- //[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
- //[5] Name ::= NameStartChar (NameChar)*
- 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
- var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
- var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
- //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
- //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(',')
- //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
- //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
- var S_TAG = 0;//tag name offerring
- var S_ATTR = 1;//attr name offerring
- var S_ATTR_SPACE=2;//attr name end and space offer
- var S_EQ = 3;//=space?
- var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
- var S_ATTR_END = 5;//attr value end and no space(quot end)
- var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
- var S_TAG_CLOSE = 7;//closed el<el />
- /**
- * Creates an error that will not be caught by XMLReader aka the SAX parser.
- *
- * @param {string} message
- * @param {any?} locator Optional, can provide details about the location in the source
- * @constructor
- */
- function ParseError(message, locator) {
- this.message = message
- this.locator = locator
- if(Error.captureStackTrace) Error.captureStackTrace(this, ParseError);
- }
- ParseError.prototype = new Error();
- ParseError.prototype.name = ParseError.name
- function XMLReader(){
- }
- XMLReader.prototype = {
- parse:function(source,defaultNSMap,entityMap){
- var domBuilder = this.domBuilder;
- domBuilder.startDocument();
- _copy(defaultNSMap ,defaultNSMap = {})
- parse(source,defaultNSMap,entityMap,
- domBuilder,this.errorHandler);
- domBuilder.endDocument();
- }
- }
- function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
- function fixedFromCharCode(code) {
- // String.prototype.fromCharCode does not supports
- // > 2 bytes unicode chars directly
- if (code > 0xffff) {
- code -= 0x10000;
- var surrogate1 = 0xd800 + (code >> 10)
- , surrogate2 = 0xdc00 + (code & 0x3ff);
- return String.fromCharCode(surrogate1, surrogate2);
- } else {
- return String.fromCharCode(code);
- }
- }
- function entityReplacer(a){
- var k = a.slice(1,-1);
- if (Object.hasOwnProperty.call(entityMap, k)) {
- return entityMap[k];
- }else if(k.charAt(0) === '#'){
- return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
- }else{
- errorHandler.error('entity not found:'+a);
- return a;
- }
- }
- function appendText(end){//has some bugs
- if(end>start){
- var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
- locator&&position(start);
- domBuilder.characters(xt,0,end-start);
- start = end
- }
- }
- function position(p,m){
- while(p>=lineEnd && (m = linePattern.exec(source))){
- lineStart = m.index;
- lineEnd = lineStart + m[0].length;
- locator.lineNumber++;
- //console.log('line++:',locator,startPos,endPos)
- }
- locator.columnNumber = p-lineStart+1;
- }
- var lineStart = 0;
- var lineEnd = 0;
- var linePattern = /.*(?:\r\n?|\n)|.*$/g
- var locator = domBuilder.locator;
- var parseStack = [{currentNSMap:defaultNSMapCopy}]
- var closeMap = {};
- var start = 0;
- while(true){
- try{
- var tagStart = source.indexOf('<',start);
- if(tagStart<0){
- if(!source.substr(start).match(/^\s*$/)){
- var doc = domBuilder.doc;
- var text = doc.createTextNode(source.substr(start));
- doc.appendChild(text);
- domBuilder.currentElement = text;
- }
- return;
- }
- if(tagStart>start){
- appendText(tagStart);
- }
- switch(source.charAt(tagStart+1)){
- case '/':
- var end = source.indexOf('>',tagStart+3);
- var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, '');
- var config = parseStack.pop();
- if(end<0){
- tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
- errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
- end = tagStart+1+tagName.length;
- }else if(tagName.match(/\s</)){
- tagName = tagName.replace(/[\s<].*/,'');
- errorHandler.error("end tag name: "+tagName+' maybe not complete');
- end = tagStart+1+tagName.length;
- }
- var localNSMap = config.localNSMap;
- var endMatch = config.tagName == tagName;
- var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase()
- if(endIgnoreCaseMach){
- domBuilder.endElement(config.uri,config.localName,tagName);
- if(localNSMap){
- for(var prefix in localNSMap){
- domBuilder.endPrefixMapping(prefix) ;
- }
- }
- if(!endMatch){
- errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName ); // No known test case
- }
- }else{
- parseStack.push(config)
- }
- end++;
- break;
- // end elment
- case '?':// <?...?>
- locator&&position(tagStart);
- end = parseInstruction(source,tagStart,domBuilder);
- break;
- case '!':// <!doctype,<![CDATA,<!--
- locator&&position(tagStart);
- end = parseDCC(source,tagStart,domBuilder,errorHandler);
- break;
- default:
- locator&&position(tagStart);
- var el = new ElementAttributes();
- var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
- //elStartEnd
- var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
- var len = el.length;
- if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
- el.closed = true;
- if(!entityMap.nbsp){
- errorHandler.warning('unclosed xml attribute');
- }
- }
- if(locator && len){
- var locator2 = copyLocator(locator,{});
- //try{//attribute position fixed
- for(var i = 0;i<len;i++){
- var a = el[i];
- position(a.offset);
- a.locator = copyLocator(locator,{});
- }
- domBuilder.locator = locator2
- if(appendElement(el,domBuilder,currentNSMap)){
- parseStack.push(el)
- }
- domBuilder.locator = locator;
- }else{
- if(appendElement(el,domBuilder,currentNSMap)){
- parseStack.push(el)
- }
- }
- if (NAMESPACE.isHTML(el.uri) && !el.closed) {
- end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
- } else {
- end++;
- }
- }
- }catch(e){
- if (e instanceof ParseError) {
- throw e;
- }
- errorHandler.error('element parse error: '+e)
- end = -1;
- }
- if(end>start){
- start = end;
- }else{
- //TODO: 这里有可能sax回退,有位置错误风险
- appendText(Math.max(tagStart,start)+1);
- }
- }
- }
- function copyLocator(f,t){
- t.lineNumber = f.lineNumber;
- t.columnNumber = f.columnNumber;
- return t;
- }
- /**
- * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
- * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
- */
- function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
- /**
- * @param {string} qname
- * @param {string} value
- * @param {number} startIndex
- */
- function addAttribute(qname, value, startIndex) {
- if (el.attributeNames.hasOwnProperty(qname)) {
- errorHandler.fatalError('Attribute ' + qname + ' redefined')
- }
- el.addValue(
- qname,
- // @see https://www.w3.org/TR/xml/#AVNormalize
- // since the xmldom sax parser does not "interpret" DTD the following is not implemented:
- // - recursive replacement of (DTD) entity references
- // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA
- value.replace(/[\t\n\r]/g, ' ').replace(/&#?\w+;/g, entityReplacer),
- startIndex
- )
- }
- var attrName;
- var value;
- var p = ++start;
- var s = S_TAG;//status
- while(true){
- var c = source.charAt(p);
- switch(c){
- case '=':
- if(s === S_ATTR){//attrName
- attrName = source.slice(start,p);
- s = S_EQ;
- }else if(s === S_ATTR_SPACE){
- s = S_EQ;
- }else{
- //fatalError: equal must after attrName or space after attrName
- throw new Error('attribute equal must after attrName'); // No known test case
- }
- break;
- case '\'':
- case '"':
- if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
- ){//equal
- if(s === S_ATTR){
- errorHandler.warning('attribute value must after "="')
- attrName = source.slice(start,p)
- }
- start = p+1;
- p = source.indexOf(c,start)
- if(p>0){
- value = source.slice(start, p);
- addAttribute(attrName, value, start-1);
- s = S_ATTR_END;
- }else{
- //fatalError: no end quot match
- throw new Error('attribute value no end \''+c+'\' match');
- }
- }else if(s == S_ATTR_NOQUOT_VALUE){
- value = source.slice(start, p);
- addAttribute(attrName, value, start);
- errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
- start = p+1;
- s = S_ATTR_END
- }else{
- //fatalError: no equal before
- throw new Error('attribute value must after "="'); // No known test case
- }
- break;
- case '/':
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));
- case S_ATTR_END:
- case S_TAG_SPACE:
- case S_TAG_CLOSE:
- s =S_TAG_CLOSE;
- el.closed = true;
- case S_ATTR_NOQUOT_VALUE:
- case S_ATTR:
- case S_ATTR_SPACE:
- break;
- //case S_EQ:
- default:
- throw new Error("attribute invalid close char('/')") // No known test case
- }
- break;
- case ''://end document
- errorHandler.error('unexpected end of input');
- if(s == S_TAG){
- el.setTagName(source.slice(start,p));
- }
- return p;
- case '>':
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));
- case S_ATTR_END:
- case S_TAG_SPACE:
- case S_TAG_CLOSE:
- break;//normal
- case S_ATTR_NOQUOT_VALUE://Compatible state
- case S_ATTR:
- value = source.slice(start,p);
- if(value.slice(-1) === '/'){
- el.closed = true;
- value = value.slice(0,-1)
- }
- case S_ATTR_SPACE:
- if(s === S_ATTR_SPACE){
- value = attrName;
- }
- if(s == S_ATTR_NOQUOT_VALUE){
- errorHandler.warning('attribute "'+value+'" missed quot(")!');
- addAttribute(attrName, value, start)
- }else{
- if(!NAMESPACE.isHTML(currentNSMap['']) || !value.match(/^(?:disabled|checked|selected)$/i)){
- errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
- }
- addAttribute(value, value, start)
- }
- break;
- case S_EQ:
- throw new Error('attribute value missed!!');
- }
- // console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
- return p;
- /*xml space '\x20' | #x9 | #xD | #xA; */
- case '\u0080':
- c = ' ';
- default:
- if(c<= ' '){//space
- switch(s){
- case S_TAG:
- el.setTagName(source.slice(start,p));//tagName
- s = S_TAG_SPACE;
- break;
- case S_ATTR:
- attrName = source.slice(start,p)
- s = S_ATTR_SPACE;
- break;
- case S_ATTR_NOQUOT_VALUE:
- var value = source.slice(start, p);
- errorHandler.warning('attribute "'+value+'" missed quot(")!!');
- addAttribute(attrName, value, start)
- case S_ATTR_END:
- s = S_TAG_SPACE;
- break;
- //case S_TAG_SPACE:
- //case S_EQ:
- //case S_ATTR_SPACE:
- // void();break;
- //case S_TAG_CLOSE:
- //ignore warning
- }
- }else{//not space
- //S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
- //S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
- switch(s){
- //case S_TAG:void();break;
- //case S_ATTR:void();break;
- //case S_ATTR_NOQUOT_VALUE:void();break;
- case S_ATTR_SPACE:
- var tagName = el.tagName;
- if (!NAMESPACE.isHTML(currentNSMap['']) || !attrName.match(/^(?:disabled|checked|selected)$/i)) {
- errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!')
- }
- addAttribute(attrName, attrName, start);
- start = p;
- s = S_ATTR;
- break;
- case S_ATTR_END:
- errorHandler.warning('attribute space is required"'+attrName+'"!!')
- case S_TAG_SPACE:
- s = S_ATTR;
- start = p;
- break;
- case S_EQ:
- s = S_ATTR_NOQUOT_VALUE;
- start = p;
- break;
- case S_TAG_CLOSE:
- throw new Error("elements closed character '/' and '>' must be connected to");
- }
- }
- }//end outer switch
- //console.log('p++',p)
- p++;
- }
- }
- /**
- * @return true if has new namespace define
- */
- function appendElement(el,domBuilder,currentNSMap){
- var tagName = el.tagName;
- var localNSMap = null;
- //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
- var i = el.length;
- while(i--){
- var a = el[i];
- var qName = a.qName;
- var value = a.value;
- var nsp = qName.indexOf(':');
- if(nsp>0){
- var prefix = a.prefix = qName.slice(0,nsp);
- var localName = qName.slice(nsp+1);
- var nsPrefix = prefix === 'xmlns' && localName
- }else{
- localName = qName;
- prefix = null
- nsPrefix = qName === 'xmlns' && ''
- }
- //can not set prefix,because prefix !== ''
- a.localName = localName ;
- //prefix == null for no ns prefix attribute
- if(nsPrefix !== false){//hack!!
- if(localNSMap == null){
- localNSMap = {}
- //console.log(currentNSMap,0)
- _copy(currentNSMap,currentNSMap={})
- //console.log(currentNSMap,1)
- }
- currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
- a.uri = NAMESPACE.XMLNS
- domBuilder.startPrefixMapping(nsPrefix, value)
- }
- }
- var i = el.length;
- while(i--){
- a = el[i];
- var prefix = a.prefix;
- if(prefix){//no prefix attribute has no namespace
- if(prefix === 'xml'){
- a.uri = NAMESPACE.XML;
- }if(prefix !== 'xmlns'){
- a.uri = currentNSMap[prefix || '']
- //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
- }
- }
- }
- var nsp = tagName.indexOf(':');
- if(nsp>0){
- prefix = el.prefix = tagName.slice(0,nsp);
- localName = el.localName = tagName.slice(nsp+1);
- }else{
- prefix = null;//important!!
- localName = el.localName = tagName;
- }
- //no prefix element has default namespace
- var ns = el.uri = currentNSMap[prefix || ''];
- domBuilder.startElement(ns,localName,tagName,el);
- //endPrefixMapping and startPrefixMapping have not any help for dom builder
- //localNSMap = null
- if(el.closed){
- domBuilder.endElement(ns,localName,tagName);
- if(localNSMap){
- for(prefix in localNSMap){
- domBuilder.endPrefixMapping(prefix)
- }
- }
- }else{
- el.currentNSMap = currentNSMap;
- el.localNSMap = localNSMap;
- //parseStack.push(el);
- return true;
- }
- }
- function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
- if(/^(?:script|textarea)$/i.test(tagName)){
- var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
- var text = source.substring(elStartEnd+1,elEndStart);
- if(/[&<]/.test(text)){
- if(/^script$/i.test(tagName)){
- //if(!/\]\]>/.test(text)){
- //lexHandler.startCDATA();
- domBuilder.characters(text,0,text.length);
- //lexHandler.endCDATA();
- return elEndStart;
- //}
- }//}else{//text area
- text = text.replace(/&#?\w+;/g,entityReplacer);
- domBuilder.characters(text,0,text.length);
- return elEndStart;
- //}
- }
- }
- return elStartEnd+1;
- }
- function fixSelfClosed(source,elStartEnd,tagName,closeMap){
- //if(tagName in closeMap){
- var pos = closeMap[tagName];
- if(pos == null){
- //console.log(tagName)
- pos = source.lastIndexOf('</'+tagName+'>')
- if(pos<elStartEnd){//忘记闭合
- pos = source.lastIndexOf('</'+tagName)
- }
- closeMap[tagName] =pos
- }
- return pos<elStartEnd;
- //}
- }
- function _copy(source,target){
- for(var n in source){target[n] = source[n]}
- }
- function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
- var next= source.charAt(start+2)
- switch(next){
- case '-':
- if(source.charAt(start + 3) === '-'){
- var end = source.indexOf('-->',start+4);
- //append comment source.substring(4,end)//<!--
- if(end>start){
- domBuilder.comment(source,start+4,end-start-4);
- return end+3;
- }else{
- errorHandler.error("Unclosed comment");
- return -1;
- }
- }else{
- //error
- return -1;
- }
- default:
- if(source.substr(start+3,6) == 'CDATA['){
- var end = source.indexOf(']]>',start+9);
- domBuilder.startCDATA();
- domBuilder.characters(source,start+9,end-start-9);
- domBuilder.endCDATA()
- return end+3;
- }
- //<!DOCTYPE
- //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
- var matchs = split(source,start);
- var len = matchs.length;
- if(len>1 && /!doctype/i.test(matchs[0][0])){
- var name = matchs[1][0];
- var pubid = false;
- var sysid = false;
- if(len>3){
- if(/^public$/i.test(matchs[2][0])){
- pubid = matchs[3][0];
- sysid = len>4 && matchs[4][0];
- }else if(/^system$/i.test(matchs[2][0])){
- sysid = matchs[3][0];
- }
- }
- var lastMatch = matchs[len-1]
- domBuilder.startDTD(name, pubid, sysid);
- domBuilder.endDTD();
- return lastMatch.index+lastMatch[0].length
- }
- }
- return -1;
- }
- function parseInstruction(source,start,domBuilder){
- var end = source.indexOf('?>',start);
- if(end){
- var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
- if(match){
- var len = match[0].length;
- domBuilder.processingInstruction(match[1], match[2]) ;
- return end+2;
- }else{//error
- return -1;
- }
- }
- return -1;
- }
- function ElementAttributes(){
- this.attributeNames = {}
- }
- ElementAttributes.prototype = {
- setTagName:function(tagName){
- if(!tagNamePattern.test(tagName)){
- throw new Error('invalid tagName:'+tagName)
- }
- this.tagName = tagName
- },
- addValue:function(qName, value, offset) {
- if(!tagNamePattern.test(qName)){
- throw new Error('invalid attribute:'+qName)
- }
- this.attributeNames[qName] = this.length;
- this[this.length++] = {qName:qName,value:value,offset:offset}
- },
- length:0,
- getLocalName:function(i){return this[i].localName},
- getLocator:function(i){return this[i].locator},
- getQName:function(i){return this[i].qName},
- getURI:function(i){return this[i].uri},
- getValue:function(i){return this[i].value}
- // ,getIndex:function(uri, localName)){
- // if(localName){
- //
- // }else{
- // var qName = uri
- // }
- // },
- // getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
- // getType:function(uri,localName){}
- // getType:function(i){},
- }
- function split(source,start){
- var match;
- var buf = [];
- var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
- reg.lastIndex = start;
- reg.exec(source);//skip <
- while(match = reg.exec(source)){
- buf.push(match);
- if(match[1])return buf;
- }
- }
- exports.XMLReader = XMLReader;
- exports.ParseError = ParseError;
- /***/ }),
- /* 17 */
- /***/ (function(module, exports) {
- //copyright Ryan Day 2010 <http://ryanday.org>, Joscha Feth 2013 <http://www.feth.com> [MIT Licensed]
- 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";
- var element_non_start_char = "\-.0-9\u00B7\u0300-\u036F\u203F\u2040";
- var element_replace = new RegExp("^([^" + element_start_char + "])|^((x|X)(m|M)(l|L))|([^" + element_start_char + element_non_start_char + "])", "g");
- var not_safe_in_xml = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm;
- var objKeys = function (obj) {
- var l = [];
- if (obj instanceof Object) {
- for (var k in obj) {
- if (obj.hasOwnProperty(k)) {
- l.push(k);
- }
- }
- }
- return l;
- };
- var process_to_xml = function (node_data, options) {
- var makeNode = function (name, content, attributes, level, hasSubNodes) {
- var indent_value = options.indent !== undefined ? options.indent : "\t";
- var indent = options.prettyPrint ? '\n' + new Array(level).join(indent_value) : '';
- if (options.removeIllegalNameCharacters) {
- name = name.replace(element_replace, '_');
- }
- var node = [indent, '<', name, attributes || ''];
- if (content && content.length > 0) {
- node.push('>');
- node.push(content);
- hasSubNodes && node.push(indent);
- node.push('</');
- node.push(name);
- node.push('>');
- } else {
- node.push('/>');
- }
- return node.join('');
- };
- return function fn(node_data, node_descriptor, level) {
- var type = typeof node_data;
- if (Array.isArray ? Array.isArray(node_data) : node_data instanceof Array) {
- type = 'array';
- } else if (node_data instanceof Date) {
- type = 'date';
- }
- switch (type) {
- //if value is an array create child nodes from values
- case 'array':
- var ret = [];
- node_data.map(function (v) {
- ret.push(fn(v, 1, level + 1));
- //entries that are values of an array are the only ones that can be special node descriptors
- });
- options.prettyPrint && ret.push('\n');
- return ret.join('');
- break;
- case 'date':
- // cast dates to ISO 8601 date (soap likes it)
- return node_data.toJSON ? node_data.toJSON() : node_data + '';
- break;
- case 'object':
- var nodes = [];
- for (var name in node_data) {
- if (node_data.hasOwnProperty(name)) {
- if (node_data[name] instanceof Array) {
- for (var j = 0; j < node_data[name].length; j++) {
- if (node_data[name].hasOwnProperty(j)) {
- nodes.push(makeNode(name, fn(node_data[name][j], 0, level + 1), null, level + 1, objKeys(node_data[name][j]).length));
- }
- }
- } else {
- nodes.push(makeNode(name, fn(node_data[name], 0, level + 1), null, level + 1));
- }
- }
- }
- options.prettyPrint && nodes.length > 0 && nodes.push('\n');
- return nodes.join('');
- break;
- case 'function':
- return node_data();
- break;
- default:
- return options.escape ? esc(node_data) : '' + node_data;
- }
- }(node_data, 0, 0);
- };
- var xml_header = function (standalone) {
- var ret = ['<?xml version="1.0" encoding="UTF-8"'];
- if (standalone) {
- ret.push(' standalone="yes"');
- }
- ret.push('?>');
- return ret.join('');
- };
- function esc(str) {
- return ('' + str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/'/g, ''').replace(/"/g, '"').replace(not_safe_in_xml, '');
- }
- module.exports = function (obj, options) {
- if (!options) {
- options = {
- xmlHeader: {
- standalone: true
- },
- prettyPrint: true,
- indent: " ",
- escape: true
- };
- }
- if (typeof obj == 'string') {
- try {
- obj = JSON.parse(obj.toString());
- } catch (e) {
- return false;
- }
- }
- var xmlheader = '';
- var docType = '';
- if (options) {
- if (typeof options == 'object') {
- // our config is an object
- if (options.xmlHeader) {
- // the user wants an xml header
- xmlheader = xml_header(!!options.xmlHeader.standalone);
- }
- if (typeof options.docType != 'undefined') {
- docType = '<!DOCTYPE ' + options.docType + '>';
- }
- } else {
- // our config is a boolean value, so just add xml header
- xmlheader = xml_header();
- }
- }
- options = options || {};
- var ret = [xmlheader, options.prettyPrint && docType ? '\n' : '', docType, process_to_xml(obj, options)];
- return ret.join('').replace(/\n{2,}/g, '\n').replace(/\s+$/g, '');
- };
- /***/ }),
- /* 18 */
- /***/ (function(module, exports, __webpack_require__) {
- var session = __webpack_require__(5);
- var util = __webpack_require__(0);
- var originApiMap = {};
- var transferToTaskMethod = function (apiMap, apiName) {
- originApiMap[apiName] = apiMap[apiName];
- apiMap[apiName] = function (params, callback) {
- if (params.SkipTask) {
- originApiMap[apiName].call(this, params, callback);
- } else {
- this._addTask(apiName, params, callback);
- }
- };
- };
- var initTask = function (cos) {
- var queue = [];
- var tasks = {};
- var uploadingFileCount = 0;
- var nextUploadIndex = 0;
- // 接口返回简略的任务信息
- var formatTask = function (task) {
- var t = {
- id: task.id,
- Bucket: task.Bucket,
- Region: task.Region,
- Key: task.Key,
- FilePath: task.FilePath,
- state: task.state,
- loaded: task.loaded,
- size: task.size,
- speed: task.speed,
- percent: task.percent,
- hashPercent: task.hashPercent,
- error: task.error
- };
- if (task.FilePath) t.FilePath = task.FilePath;
- if (task._custom) t._custom = task._custom; // 控制台使用
- return t;
- };
- var emitListUpdate = function () {
- var timer;
- var emit = function () {
- timer = 0;
- cos.emit('task-list-update', { list: util.map(queue, formatTask) });
- cos.emit('list-update', { list: util.map(queue, formatTask) });
- };
- return function () {
- if (!timer) timer = setTimeout(emit);
- };
- }();
- var clearQueue = function () {
- if (queue.length <= cos.options.UploadQueueSize) return;
- for (var i = 0; i < nextUploadIndex && // 小于当前操作的 index 才清理
- i < queue.length && // 大于队列才清理
- queue.length > cos.options.UploadQueueSize // 如果还太多,才继续清理
- ;) {
- var isActive = queue[i].state === 'waiting' || queue[i].state === 'checking' || queue[i].state === 'uploading';
- if (!queue[i] || !isActive) {
- tasks[queue[i].id] && delete tasks[queue[i].id];
- queue.splice(i, 1);
- nextUploadIndex--;
- } else {
- i++;
- }
- }
- emitListUpdate();
- };
- var startNextTask = function () {
- // 检查是否允许增加执行进程
- if (uploadingFileCount >= cos.options.FileParallelLimit) return;
- // 跳过不可执行的任务
- while (queue[nextUploadIndex] && queue[nextUploadIndex].state !== 'waiting') nextUploadIndex++;
- // 检查是否已遍历结束
- if (nextUploadIndex >= queue.length) return;
- // 上传该遍历到的任务
- var task = queue[nextUploadIndex];
- nextUploadIndex++;
- uploadingFileCount++;
- task.state = 'checking';
- task.params.onTaskStart && task.params.onTaskStart(formatTask(task));
- !task.params.UploadData && (task.params.UploadData = {});
- var apiParams = util.formatParams(task.api, task.params);
- originApiMap[task.api].call(cos, apiParams, function (err, data) {
- if (!cos._isRunningTask(task.id)) return;
- if (task.state === 'checking' || task.state === 'uploading') {
- task.state = err ? 'error' : 'success';
- err && (task.error = err);
- uploadingFileCount--;
- emitListUpdate();
- startNextTask();
- task.callback && task.callback(err, data);
- if (task.state === 'success') {
- if (task.params) {
- delete task.params.UploadData;
- delete task.params.Body;
- delete task.params;
- }
- delete task.callback;
- }
- }
- clearQueue();
- });
- emitListUpdate();
- // 异步执行下一个任务
- setTimeout(startNextTask);
- };
- var killTask = function (id, switchToState) {
- var task = tasks[id];
- if (!task) return;
- var waiting = task && task.state === 'waiting';
- var running = task && (task.state === 'checking' || task.state === 'uploading');
- if (switchToState === 'canceled' && task.state !== 'canceled' || switchToState === 'paused' && waiting || switchToState === 'paused' && running) {
- if (switchToState === 'paused' && task.params.Body && typeof task.params.Body.pipe === 'function') {
- console.error('stream not support pause');
- return;
- }
- task.state = switchToState;
- cos.emit('inner-kill-task', { TaskId: id, toState: switchToState });
- try {
- var UploadId = task && task.params && task.params.UploadData.UploadId;
- } catch (e) {}
- if (switchToState === 'canceled' && UploadId) session.removeUsing(UploadId);
- emitListUpdate();
- if (running) {
- uploadingFileCount--;
- startNextTask();
- }
- if (switchToState === 'canceled') {
- if (task.params) {
- delete task.params.UploadData;
- delete task.params.Body;
- delete task.params;
- }
- delete task.callback;
- }
- }
- clearQueue();
- };
- cos._addTasks = function (taskList) {
- util.each(taskList, function (task) {
- cos._addTask(task.api, task.params, task.callback, true);
- });
- emitListUpdate();
- };
- var isTaskReadyWarning = true;
- cos._addTask = function (api, params, callback, ignoreAddEvent) {
- // 复制参数对象
- params = util.formatParams(api, params);
- // 生成 id
- var id = util.uuid();
- params.TaskId = id;
- params.onTaskReady && params.onTaskReady(id);
- if (params.TaskReady) {
- params.TaskReady(id);
- isTaskReadyWarning && console.warn('warning: Param "TaskReady" has been deprecated. Please use "onTaskReady" instead.');
- isTaskReadyWarning = false;
- }
- var task = {
- // env
- params: params,
- callback: callback,
- api: api,
- index: queue.length,
- // task
- id: id,
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- FilePath: params.FilePath || '',
- state: 'waiting',
- loaded: 0,
- size: 0,
- speed: 0,
- percent: 0,
- hashPercent: 0,
- error: null,
- _custom: params._custom
- };
- var onHashProgress = params.onHashProgress;
- params.onHashProgress = function (info) {
- if (!cos._isRunningTask(task.id)) return;
- task.hashPercent = info.percent;
- onHashProgress && onHashProgress(info);
- emitListUpdate();
- };
- var onProgress = params.onProgress;
- params.onProgress = function (info) {
- if (!cos._isRunningTask(task.id)) return;
- task.state === 'checking' && (task.state = 'uploading');
- task.loaded = info.loaded;
- task.speed = info.speed;
- task.percent = info.percent;
- onProgress && onProgress(info);
- emitListUpdate();
- };
- // 异步获取 filesize
- util.getFileSize(api, params, function (err, size) {
- // 开始处理上传
- if (err) return callback(util.error(err)); // 如果获取大小出错,不加入队列
- // 获取完文件大小再把任务加入队列
- tasks[id] = task;
- queue.push(task);
- task.size = size;
- !ignoreAddEvent && emitListUpdate();
- startNextTask();
- clearQueue();
- });
- return id;
- };
- cos._isRunningTask = function (id) {
- var task = tasks[id];
- return !!(task && (task.state === 'checking' || task.state === 'uploading'));
- };
- cos.getTaskList = function () {
- return util.map(queue, formatTask);
- };
- cos.cancelTask = function (id) {
- killTask(id, 'canceled');
- };
- cos.pauseTask = function (id) {
- killTask(id, 'paused');
- };
- cos.restartTask = function (id) {
- var task = tasks[id];
- if (task && (task.state === 'paused' || task.state === 'error')) {
- task.state = 'waiting';
- emitListUpdate();
- nextUploadIndex = Math.min(nextUploadIndex, task.index);
- startNextTask();
- }
- };
- cos.isUploadRunning = function () {
- return uploadingFileCount || nextUploadIndex < queue.length;
- };
- };
- module.exports.transferToTaskMethod = transferToTaskMethod;
- module.exports.init = initTask;
- /***/ }),
- /* 19 */
- /***/ (function(module, exports, __webpack_require__) {
- var REQUEST = __webpack_require__(20);
- var util = __webpack_require__(0);
- // Bucket 相关
- /**
- * 获取用户的 bucket 列表
- * @param {Object} params 回调函数,必须,下面为参数列表
- * 无特殊参数
- * @param {Function} callback 回调函数,必须
- */
- function getService(params, callback) {
- if (typeof params === 'function') {
- callback = params;
- params = {};
- }
- var protocol = this.options.Protocol || (util.isBrowser && location.protocol === 'http:' ? 'http:' : 'https:');
- var domain = this.options.ServiceDomain;
- var appId = params.AppId || this.options.appId;
- var region = params.Region;
- if (domain) {
- domain = domain.replace(/\{\{AppId\}\}/ig, appId || '').replace(/\{\{Region\}\}/ig, region || '').replace(/\{\{.*?\}\}/ig, '');
- if (!/^[a-zA-Z]+:\/\//.test(domain)) {
- domain = protocol + '//' + domain;
- }
- if (domain.slice(-1) === '/') {
- domain = domain.slice(0, -1);
- }
- } else if (region) {
- domain = protocol + '//cos.' + region + '.myqcloud.com';
- } else {
- domain = protocol + '//service.cos.myqcloud.com';
- }
- var SignHost = '';
- var standardHost = region ? 'cos.' + region + '.myqcloud.com' : 'service.cos.myqcloud.com';
- var urlHost = domain.replace(/^https?:\/\/([^/]+)(\/.*)?$/, '$1');
- if (standardHost === urlHost) SignHost = standardHost;
- submitRequest.call(this, {
- Action: 'name/cos:GetService',
- url: domain,
- method: 'GET',
- headers: params.Headers,
- SignHost: SignHost
- }, function (err, data) {
- if (err) return callback(err);
- var buckets = data && data.ListAllMyBucketsResult && data.ListAllMyBucketsResult.Buckets && data.ListAllMyBucketsResult.Buckets.Bucket || [];
- buckets = util.isArray(buckets) ? buckets : [buckets];
- var owner = data && data.ListAllMyBucketsResult && data.ListAllMyBucketsResult.Owner || {};
- callback(null, {
- Buckets: buckets,
- Owner: owner,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 创建 Bucket,并初始化访问权限
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.ACL 用户自定义文件权限,可以设置:private,public-read;默认值:private,非必须
- * @param {String} params.GrantRead 赋予被授权者读的权限,格式x-cos-grant-read: uin=" ",uin=" ",非必须
- * @param {String} params.GrantWrite 赋予被授权者写的权限,格式x-cos-grant-write: uin=" ",uin=" ",非必须
- * @param {String} params.GrantFullControl 赋予被授权者读写权限,格式x-cos-grant-full-control: uin=" ",uin=" ",非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {String} data.Location 操作地址
- */
- function putBucket(params, callback) {
- var self = this;
- var xml = '';
- if (params['BucketAZConfig']) {
- var CreateBucketConfiguration = {
- BucketAZConfig: params.BucketAZConfig
- };
- xml = util.json2xml({ CreateBucketConfiguration: CreateBucketConfiguration });
- }
- submitRequest.call(this, {
- Action: 'name/cos:PutBucket',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- body: xml
- }, function (err, data) {
- if (err) return callback(err);
- var url = getUrl({
- protocol: self.options.Protocol,
- domain: self.options.Domain,
- bucket: params.Bucket,
- region: params.Region,
- isLocation: true
- });
- callback(null, {
- Location: url,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 查看是否存在该Bucket,是否有权限访问
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Boolean} data.BucketExist Bucket是否存在
- * @return {Boolean} data.BucketAuth 是否有 Bucket 的访问权限
- */
- function headBucket(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:HeadBucket',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- method: 'HEAD'
- }, callback);
- }
- /**
- * 获取 Bucket 下的 object 列表
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Prefix 前缀匹配,用来规定返回的文件前缀地址,非必须
- * @param {String} params.Delimiter 定界符为一个符号,如果有Prefix,则将Prefix到delimiter之间的相同路径归为一类,非必须
- * @param {String} params.Marker 默认以UTF-8二进制顺序列出条目,所有列出条目从marker开始,非必须
- * @param {String} params.MaxKeys 单次返回最大的条目数量,默认1000,非必须
- * @param {String} params.EncodingType 规定返回值的编码方式,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.ListBucketResult 返回的 object 列表信息
- */
- function getBucket(params, callback) {
- var reqParams = {};
- reqParams['prefix'] = params['Prefix'] || '';
- reqParams['delimiter'] = params['Delimiter'];
- reqParams['marker'] = params['Marker'];
- reqParams['max-keys'] = params['MaxKeys'];
- reqParams['encoding-type'] = params['EncodingType'];
- submitRequest.call(this, {
- Action: 'name/cos:GetBucket',
- ResourceKey: reqParams['prefix'],
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- qs: reqParams
- }, function (err, data) {
- if (err) return callback(err);
- var ListBucketResult = data.ListBucketResult || {};
- var Contents = ListBucketResult.Contents || [];
- var CommonPrefixes = ListBucketResult.CommonPrefixes || [];
- Contents = util.isArray(Contents) ? Contents : [Contents];
- CommonPrefixes = util.isArray(CommonPrefixes) ? CommonPrefixes : [CommonPrefixes];
- var result = util.clone(ListBucketResult);
- util.extend(result, {
- Contents: Contents,
- CommonPrefixes: CommonPrefixes,
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- /**
- * 删除 Bucket
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {String} data.Location 操作地址
- */
- function deleteBucket(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucket',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- method: 'DELETE'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 设置 Bucket 的 权限列表
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.ACL 用户自定义文件权限,可以设置:private,public-read;默认值:private,非必须
- * @param {String} params.GrantRead 赋予被授权者读的权限,格式x-cos-grant-read: uin=" ",uin=" ",非必须
- * @param {String} params.GrantWrite 赋予被授权者写的权限,格式x-cos-grant-write: uin=" ",uin=" ",非必须
- * @param {String} params.GrantFullControl 赋予被授权者读写权限,格式x-cos-grant-full-control: uin=" ",uin=" ",非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function putBucketAcl(params, callback) {
- var headers = params.Headers;
- var xml = '';
- if (params['AccessControlPolicy']) {
- var AccessControlPolicy = util.clone(params['AccessControlPolicy'] || {});
- var Grants = AccessControlPolicy.Grants || AccessControlPolicy.Grant;
- Grants = util.isArray(Grants) ? Grants : [Grants];
- delete AccessControlPolicy.Grant;
- delete AccessControlPolicy.Grants;
- AccessControlPolicy.AccessControlList = { Grant: Grants };
- xml = util.json2xml({ AccessControlPolicy: AccessControlPolicy });
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- }
- // Grant Header 去重
- util.each(headers, function (val, key) {
- if (key.indexOf('x-cos-grant-') === 0) {
- headers[key] = uniqGrant(headers[key]);
- }
- });
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketACL',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: headers,
- action: 'acl',
- body: xml
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的 权限列表
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.AccessControlPolicy 访问权限信息
- */
- function getBucketAcl(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketACL',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'acl'
- }, function (err, data) {
- if (err) return callback(err);
- var AccessControlPolicy = data.AccessControlPolicy || {};
- var Owner = AccessControlPolicy.Owner || {};
- var Grant = AccessControlPolicy.AccessControlList.Grant || [];
- Grant = util.isArray(Grant) ? Grant : [Grant];
- var result = decodeAcl(AccessControlPolicy);
- if (data.headers && data.headers['x-cos-acl']) {
- result.ACL = data.headers['x-cos-acl'];
- }
- result = util.extend(result, {
- Owner: Owner,
- Grants: Grant,
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- /**
- * 设置 Bucket 的 跨域设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Object} params.CORSConfiguration 相关的跨域设置,必须
- * @param {Array} params.CORSConfiguration.CORSRules 对应的跨域规则
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function putBucketCors(params, callback) {
- var CORSConfiguration = params['CORSConfiguration'] || {};
- var CORSRules = CORSConfiguration['CORSRules'] || params['CORSRules'] || [];
- CORSRules = util.clone(util.isArray(CORSRules) ? CORSRules : [CORSRules]);
- util.each(CORSRules, function (rule) {
- util.each(['AllowedOrigin', 'AllowedHeader', 'AllowedMethod', 'ExposeHeader'], function (key) {
- var sKey = key + 's';
- var val = rule[sKey] || rule[key] || [];
- delete rule[sKey];
- rule[key] = util.isArray(val) ? val : [val];
- });
- });
- var Conf = { CORSRule: CORSRules };
- if (params.ResponseVary) Conf.ResponseVary = params.ResponseVary;
- var xml = util.json2xml({ CORSConfiguration: Conf });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketCORS',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'cors',
- headers: headers
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的 跨域设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.CORSRules Bucket的跨域设置
- */
- function getBucketCors(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketCORS',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'cors'
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.error && err.error.Code === 'NoSuchCORSConfiguration') {
- var result = {
- CORSRules: [],
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- var CORSConfiguration = data.CORSConfiguration || {};
- var CORSRules = CORSConfiguration.CORSRules || CORSConfiguration.CORSRule || [];
- CORSRules = util.clone(util.isArray(CORSRules) ? CORSRules : [CORSRules]);
- var ResponseVary = CORSConfiguration.ResponseVary;
- util.each(CORSRules, function (rule) {
- util.each(['AllowedOrigin', 'AllowedHeader', 'AllowedMethod', 'ExposeHeader'], function (key) {
- var sKey = key + 's';
- var val = rule[sKey] || rule[key] || [];
- delete rule[key];
- rule[sKey] = util.isArray(val) ? val : [val];
- });
- });
- callback(null, {
- CORSRules: CORSRules,
- ResponseVary: ResponseVary,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 删除 Bucket 的 跨域设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function deleteBucketCors(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketCORS',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'cors'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode || err.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的 地域信息
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据,包含地域信息 LocationConstraint
- */
- function getBucketLocation(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketLocation',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'location'
- }, callback);
- }
- function putBucketPolicy(params, callback) {
- var Policy = params['Policy'];
- try {
- if (typeof Policy === 'string') Policy = JSON.parse(Policy);
- } catch (e) {}
- if (!Policy || typeof Policy === 'string') return callback(util.error(new Error('Policy format error')));
- var PolicyStr = JSON.stringify(Policy);
- if (!Policy.version) Policy.version = '2.0';
- var headers = params.Headers;
- headers['Content-Type'] = 'application/json';
- headers['Content-MD5'] = util.binaryBase64(util.md5(PolicyStr));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketPolicy',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- action: 'policy',
- body: PolicyStr,
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的读取权限策略
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketPolicy(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketPolicy',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'policy',
- rawBody: true
- }, function (err, data) {
- if (err) {
- if (err.statusCode && err.statusCode === 403) {
- return callback(util.error(err, { ErrorStatus: 'Access Denied' }));
- }
- if (err.statusCode && err.statusCode === 405) {
- return callback(util.error(err, { ErrorStatus: 'Method Not Allowed' }));
- }
- if (err.statusCode && err.statusCode === 404) {
- return callback(util.error(err, { ErrorStatus: 'Policy Not Found' }));
- }
- return callback(err);
- }
- var Policy = {};
- try {
- Policy = JSON.parse(data.body);
- } catch (e) {}
- callback(null, {
- Policy: Policy,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 删除 Bucket 的 跨域设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function deleteBucketPolicy(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketPolicy',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'policy'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode || err.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 设置 Bucket 的标签
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Array} params.TagSet 标签设置,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function putBucketTagging(params, callback) {
- var Tagging = params['Tagging'] || {};
- var Tags = Tagging.TagSet || Tagging.Tags || params['Tags'] || [];
- Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
- var xml = util.json2xml({ Tagging: { TagSet: { Tag: Tags } } });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketTagging',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'tagging',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的标签设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketTagging(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketTagging',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'tagging'
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.error && (err.error === "Not Found" || err.error.Code === 'NoSuchTagSet')) {
- var result = {
- Tags: [],
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- var Tags = [];
- try {
- Tags = data.Tagging.TagSet.Tag || [];
- } catch (e) {}
- Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
- callback(null, {
- Tags: Tags,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 删除 Bucket 的 标签设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function deleteBucketTagging(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketTagging',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'tagging'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function putBucketLifecycle(params, callback) {
- var LifecycleConfiguration = params['LifecycleConfiguration'] || {};
- var Rules = LifecycleConfiguration.Rules || params.Rules || [];
- Rules = util.clone(Rules);
- var xml = util.json2xml({ LifecycleConfiguration: { Rule: Rules } });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketLifecycle',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'lifecycle',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function getBucketLifecycle(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketLifecycle',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'lifecycle'
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.error && err.error.Code === 'NoSuchLifecycleConfiguration') {
- var result = {
- Rules: [],
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- var Rules = [];
- try {
- Rules = data.LifecycleConfiguration.Rule || [];
- } catch (e) {}
- Rules = util.clone(util.isArray(Rules) ? Rules : [Rules]);
- callback(null, {
- Rules: Rules,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function deleteBucketLifecycle(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketLifecycle',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'lifecycle'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function putBucketVersioning(params, callback) {
- if (!params['VersioningConfiguration']) {
- callback(util.error(new Error('missing param VersioningConfiguration')));
- return;
- }
- var VersioningConfiguration = params['VersioningConfiguration'] || {};
- var xml = util.json2xml({ VersioningConfiguration: VersioningConfiguration });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketVersioning',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'versioning',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function getBucketVersioning(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketVersioning',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'versioning'
- }, function (err, data) {
- if (!err) {
- !data.VersioningConfiguration && (data.VersioningConfiguration = {});
- }
- callback(err, data);
- });
- }
- function putBucketReplication(params, callback) {
- var ReplicationConfiguration = util.clone(params.ReplicationConfiguration);
- var xml = util.json2xml({ ReplicationConfiguration: ReplicationConfiguration });
- xml = xml.replace(/<(\/?)Rules>/ig, '<$1Rule>');
- xml = xml.replace(/<(\/?)Tags>/ig, '<$1Tag>');
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketReplication',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'replication',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function getBucketReplication(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketReplication',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'replication'
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.error && (err.error === 'Not Found' || err.error.Code === 'ReplicationConfigurationnotFoundError')) {
- var result = {
- ReplicationConfiguration: { Rules: [] },
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- !data.ReplicationConfiguration && (data.ReplicationConfiguration = {});
- if (data.ReplicationConfiguration.Rule) {
- data.ReplicationConfiguration.Rules = util.makeArray(data.ReplicationConfiguration.Rule);
- delete data.ReplicationConfiguration.Rule;
- }
- callback(err, data);
- });
- }
- function deleteBucketReplication(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketReplication',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'replication'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 设置 Bucket 静态网站配置信息
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Object} params.WebsiteConfiguration 地域名称,必须
- * @param {Object} WebsiteConfiguration.IndexDocument 索引文档,必须
- * @param {Object} WebsiteConfiguration.ErrorDocument 错误文档,非必须
- * @param {Object} WebsiteConfiguration.RedirectAllRequestsTo 重定向所有请求,非必须
- * @param {Array} params.RoutingRules 重定向规则,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function putBucketWebsite(params, callback) {
- if (!params['WebsiteConfiguration']) {
- callback(util.error(new Error('missing param WebsiteConfiguration')));
- return;
- }
- var WebsiteConfiguration = util.clone(params['WebsiteConfiguration'] || {});
- var RoutingRules = WebsiteConfiguration['RoutingRules'] || WebsiteConfiguration['RoutingRule'] || [];
- RoutingRules = util.isArray(RoutingRules) ? RoutingRules : [RoutingRules];
- delete WebsiteConfiguration.RoutingRule;
- delete WebsiteConfiguration.RoutingRules;
- if (RoutingRules.length) WebsiteConfiguration.RoutingRules = { RoutingRule: RoutingRules };
- var xml = util.json2xml({ WebsiteConfiguration: WebsiteConfiguration });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketWebsite',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'website',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的静态网站配置信息
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketWebsite(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketWebsite',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- action: 'website'
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.error.Code === 'NoSuchWebsiteConfiguration') {
- var result = {
- WebsiteConfiguration: {},
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- var WebsiteConfiguration = data.WebsiteConfiguration || {};
- if (WebsiteConfiguration['RoutingRules']) {
- var RoutingRules = util.clone(WebsiteConfiguration['RoutingRules'].RoutingRule || []);
- RoutingRules = util.makeArray(RoutingRules);
- WebsiteConfiguration.RoutingRules = RoutingRules;
- }
- callback(null, {
- WebsiteConfiguration: WebsiteConfiguration,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 删除 Bucket 的静态网站配置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function deleteBucketWebsite(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketWebsite',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'website'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 设置 Bucket 的防盗链白名单或者黑名单
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Object} params.RefererConfiguration 地域名称,必须
- * @param {String} RefererConfiguration.Status 是否开启防盗链,枚举值:Enabled、Disabled
- * @param {String} RefererConfiguration.RefererType 防盗链类型,枚举值:Black-List、White-List,必须
- * @param {Array} RefererConfiguration.DomianList.Domain 生效域名,必须
- * @param {String} RefererConfiguration.EmptyReferConfiguration ,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function putBucketReferer(params, callback) {
- if (!params['RefererConfiguration']) {
- callback(util.error(new Error('missing param RefererConfiguration')));
- return;
- }
- var RefererConfiguration = util.clone(params['RefererConfiguration'] || {});
- var DomainList = RefererConfiguration['DomainList'] || {};
- var Domains = DomainList['Domains'] || DomainList['Domain'] || [];
- Domains = util.isArray(Domains) ? Domains : [Domains];
- if (Domains.length) RefererConfiguration.DomainList = { Domain: Domains };
- var xml = util.json2xml({ RefererConfiguration: RefererConfiguration });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketReferer',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'referer',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的防盗链白名单或者黑名单
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketReferer(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketReferer',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- action: 'referer'
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.error.Code === 'NoSuchRefererConfiguration') {
- var result = {
- WebsiteConfiguration: {},
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- var RefererConfiguration = data.RefererConfiguration || {};
- if (RefererConfiguration['DomainList']) {
- var Domains = util.makeArray(RefererConfiguration['DomainList'].Domain || []);
- RefererConfiguration.DomainList = { Domains: Domains };
- }
- callback(null, {
- RefererConfiguration: RefererConfiguration,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 设置 Bucket 自定义域名
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function putBucketDomain(params, callback) {
- var DomainConfiguration = params['DomainConfiguration'] || {};
- var DomainRule = DomainConfiguration.DomainRule || params.DomainRule || [];
- DomainRule = util.clone(DomainRule);
- var xml = util.json2xml({ DomainConfiguration: { DomainRule: DomainRule } });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketDomain',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'domain',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的自定义域名
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketDomain(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketDomain',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'domain'
- }, function (err, data) {
- if (err) return callback(err);
- var DomainRule = [];
- try {
- DomainRule = data.DomainConfiguration.DomainRule || [];
- } catch (e) {}
- DomainRule = util.clone(util.isArray(DomainRule) ? DomainRule : [DomainRule]);
- callback(null, {
- DomainRule: DomainRule,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 删除 Bucket 自定义域名
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function deleteBucketDomain(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketDomain',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'domain'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 设置 Bucket 的回源
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function putBucketOrigin(params, callback) {
- var OriginConfiguration = params['OriginConfiguration'] || {};
- var OriginRule = OriginConfiguration.OriginRule || params.OriginRule || [];
- OriginRule = util.clone(OriginRule);
- var xml = util.json2xml({ OriginConfiguration: { OriginRule: OriginRule } });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketOrigin',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'origin',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的回源
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketOrigin(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketOrigin',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'origin'
- }, function (err, data) {
- if (err) return callback(err);
- var OriginRule = [];
- try {
- OriginRule = data.OriginConfiguration.OriginRule || [];
- } catch (e) {}
- OriginRule = util.clone(util.isArray(OriginRule) ? OriginRule : [OriginRule]);
- callback(null, {
- OriginRule: OriginRule,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 删除 Bucket 的回源
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function deleteBucketOrigin(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketOrigin',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'origin'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 设置 Bucket 的日志记录
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {(Object|String)} params.BucketLoggingStatus 说明日志记录配置的状态,如果无子节点信息则意为关闭日志记录,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function putBucketLogging(params, callback) {
- var xml = util.json2xml({
- BucketLoggingStatus: params['BucketLoggingStatus'] || ''
- });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketLogging',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'logging',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的日志记录
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketLogging(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketLogging',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'logging'
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, {
- BucketLoggingStatus: data.BucketLoggingStatus,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 创建/编辑 Bucket 的清单任务
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Id 清单任务的名称,必须
- * @param {Object} params.InventoryConfiguration 包含清单的配置参数,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function putBucketInventory(params, callback) {
- var InventoryConfiguration = util.clone(params['InventoryConfiguration']);
- if (InventoryConfiguration.OptionalFields) {
- var Field = InventoryConfiguration.OptionalFields || [];
- InventoryConfiguration.OptionalFields = {
- Field: Field
- };
- }
- if (InventoryConfiguration.Destination && InventoryConfiguration.Destination.COSBucketDestination && InventoryConfiguration.Destination.COSBucketDestination.Encryption) {
- var Encryption = InventoryConfiguration.Destination.COSBucketDestination.Encryption;
- if (Object.keys(Encryption).indexOf('SSECOS') > -1) {
- Encryption['SSE-COS'] = Encryption['SSECOS'];
- delete Encryption['SSECOS'];
- }
- }
- var xml = util.json2xml({
- InventoryConfiguration: InventoryConfiguration
- });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketInventory',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'inventory',
- qs: {
- id: params['Id']
- },
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的清单任务信息
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Id 清单任务的名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function getBucketInventory(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketInventory',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'inventory',
- qs: {
- id: params['Id']
- }
- }, function (err, data) {
- if (err) return callback(err);
- var InventoryConfiguration = data['InventoryConfiguration'];
- if (InventoryConfiguration && InventoryConfiguration.OptionalFields && InventoryConfiguration.OptionalFields.Field) {
- var Field = InventoryConfiguration.OptionalFields.Field;
- if (!util.isArray(Field)) {
- Field = [Field];
- }
- InventoryConfiguration.OptionalFields = Field;
- }
- if (InventoryConfiguration.Destination && InventoryConfiguration.Destination.COSBucketDestination && InventoryConfiguration.Destination.COSBucketDestination.Encryption) {
- var Encryption = InventoryConfiguration.Destination.COSBucketDestination.Encryption;
- if (Object.keys(Encryption).indexOf('SSE-COS') > -1) {
- Encryption['SSECOS'] = Encryption['SSE-COS'];
- delete Encryption['SSE-COS'];
- }
- }
- callback(null, {
- InventoryConfiguration: InventoryConfiguration,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Bucket 的清单任务信息
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.ContinuationToken 当 COS 响应体中 IsTruncated 为 true,且 NextContinuationToken 节点中存在参数值时,您可以将这个参数作为 continuation-token 参数值,以获取下一页的清单任务信息,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function listBucketInventory(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:ListBucketInventory',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'inventory',
- qs: {
- 'continuation-token': params['ContinuationToken']
- }
- }, function (err, data) {
- if (err) return callback(err);
- var ListInventoryConfigurationResult = data['ListInventoryConfigurationResult'];
- var InventoryConfigurations = ListInventoryConfigurationResult.InventoryConfiguration || [];
- InventoryConfigurations = util.isArray(InventoryConfigurations) ? InventoryConfigurations : [InventoryConfigurations];
- delete ListInventoryConfigurationResult['InventoryConfiguration'];
- util.each(InventoryConfigurations, function (InventoryConfiguration) {
- if (InventoryConfiguration && InventoryConfiguration.OptionalFields && InventoryConfiguration.OptionalFields.Field) {
- var Field = InventoryConfiguration.OptionalFields.Field;
- if (!util.isArray(Field)) {
- Field = [Field];
- }
- InventoryConfiguration.OptionalFields = Field;
- }
- if (InventoryConfiguration.Destination && InventoryConfiguration.Destination.COSBucketDestination && InventoryConfiguration.Destination.COSBucketDestination.Encryption) {
- var Encryption = InventoryConfiguration.Destination.COSBucketDestination.Encryption;
- if (Object.keys(Encryption).indexOf('SSE-COS') > -1) {
- Encryption['SSECOS'] = Encryption['SSE-COS'];
- delete Encryption['SSE-COS'];
- }
- }
- });
- ListInventoryConfigurationResult.InventoryConfigurations = InventoryConfigurations;
- util.extend(ListInventoryConfigurationResult, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, ListInventoryConfigurationResult);
- });
- }
- /**
- * 删除 Bucket 的清单任务
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Id 清单任务的名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回数据
- */
- function deleteBucketInventory(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketInventory',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'inventory',
- qs: {
- id: params['Id']
- }
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /* 全球加速 */
- function putBucketAccelerate(params, callback) {
- if (!params['AccelerateConfiguration']) {
- callback(util.error(new Error('missing param AccelerateConfiguration')));
- return;
- }
- var configuration = { AccelerateConfiguration: params.AccelerateConfiguration || {} };
- var xml = util.json2xml(configuration);
- var headers = {};
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketAccelerate',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'accelerate',
- headers: headers
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function getBucketAccelerate(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketAccelerate',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- action: 'accelerate'
- }, function (err, data) {
- if (!err) {
- !data.AccelerateConfiguration && (data.AccelerateConfiguration = {});
- }
- callback(err, data);
- });
- }
- function putBucketEncryption(params, callback) {
- var conf = params.ServerSideEncryptionConfiguration || {};
- var Rules = conf.Rule || conf.Rules || [];
- var xml = util.json2xml({ ServerSideEncryptionConfiguration: { Rule: Rules } });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutBucketEncryption',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'encryption',
- headers: headers
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- function getBucketEncryption(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketEncryption',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'encryption'
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.code === 'NoSuchEncryptionConfiguration') {
- var result = {
- EncryptionConfiguration: { Rules: [] },
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- var Rules = util.makeArray(data.EncryptionConfiguration && data.EncryptionConfiguration.Rule || []);
- data.EncryptionConfiguration = { Rules: Rules };
- callback(err, data);
- });
- }
- function deleteBucketEncryption(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteBucketReplication',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'encryption'
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- // Object 相关
- /**
- * 取回对应Object的元数据,Head的权限与Get的权限一致
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key 文件名称,必须
- * @param {String} params.IfModifiedSince 当Object在指定时间后被修改,则返回对应Object元信息,否则返回304,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 为指定 object 的元数据,如果设置了 IfModifiedSince ,且文件未修改,则返回一个对象,NotModified 属性为 true
- * @return {Boolean} data.NotModified 是否在 IfModifiedSince 时间点之后未修改该 object,则为 true
- */
- function headObject(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:HeadObject',
- method: 'HEAD',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- VersionId: params.VersionId,
- headers: params.Headers
- }, function (err, data) {
- if (err) {
- var statusCode = err.statusCode;
- if (params.Headers['If-Modified-Since'] && statusCode && statusCode === 304) {
- return callback(null, {
- NotModified: true,
- statusCode: statusCode
- });
- }
- return callback(err);
- }
- data.ETag = util.attr(data.headers, 'etag', '');
- callback(null, data);
- });
- }
- function listObjectVersions(params, callback) {
- var reqParams = {};
- reqParams['prefix'] = params['Prefix'] || '';
- reqParams['delimiter'] = params['Delimiter'];
- reqParams['key-marker'] = params['KeyMarker'];
- reqParams['version-id-marker'] = params['VersionIdMarker'];
- reqParams['max-keys'] = params['MaxKeys'];
- reqParams['encoding-type'] = params['EncodingType'];
- submitRequest.call(this, {
- Action: 'name/cos:GetBucketObjectVersions',
- ResourceKey: reqParams['prefix'],
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- qs: reqParams,
- action: 'versions'
- }, function (err, data) {
- if (err) return callback(err);
- var ListVersionsResult = data.ListVersionsResult || {};
- var DeleteMarkers = ListVersionsResult.DeleteMarker || [];
- DeleteMarkers = util.isArray(DeleteMarkers) ? DeleteMarkers : [DeleteMarkers];
- var Versions = ListVersionsResult.Version || [];
- Versions = util.isArray(Versions) ? Versions : [Versions];
- var result = util.clone(ListVersionsResult);
- delete result.DeleteMarker;
- delete result.Version;
- util.extend(result, {
- DeleteMarkers: DeleteMarkers,
- Versions: Versions,
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- /**
- * 下载 object
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key 文件名称,必须
- * @param {WriteStream} params.Output 文件写入流,非必须
- * @param {String} params.IfModifiedSince 当Object在指定时间后被修改,则返回对应Object元信息,否则返回304,非必须
- * @param {String} params.IfUnmodifiedSince 如果文件修改时间早于或等于指定时间,才返回文件内容。否则返回 412 (precondition failed),非必须
- * @param {String} params.IfMatch 当 ETag 与指定的内容一致,才返回文件。否则返回 412 (precondition failed),非必须
- * @param {String} params.IfNoneMatch 当 ETag 与指定的内容不一致,才返回文件。否则返回304 (not modified),非必须
- * @param {String} params.ResponseContentType 设置返回头部中的 Content-Type 参数,非必须
- * @param {String} params.ResponseContentLanguage 设置返回头部中的 Content-Language 参数,非必须
- * @param {String} params.ResponseExpires 设置返回头部中的 Content-Expires 参数,非必须
- * @param {String} params.ResponseCacheControl 设置返回头部中的 Cache-Control 参数,非必须
- * @param {String} params.ResponseContentDisposition 设置返回头部中的 Content-Disposition 参数,非必须
- * @param {String} params.ResponseContentEncoding 设置返回头部中的 Content-Encoding 参数,非必须
- * @param {Function} callback 回调函数,必须
- * @param {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @param {Object} data 为对应的 object 数据,包括 body 和 headers
- */
- function getObject(params, callback) {
- var reqParams = params.Query || {};
- var reqParamsStr = params.QueryString || '';
- var onProgress = util.throttleOnProgress.call(this, 0, params.onProgress);
- reqParams['response-content-type'] = params['ResponseContentType'];
- reqParams['response-content-language'] = params['ResponseContentLanguage'];
- reqParams['response-expires'] = params['ResponseExpires'];
- reqParams['response-cache-control'] = params['ResponseCacheControl'];
- reqParams['response-content-disposition'] = params['ResponseContentDisposition'];
- reqParams['response-content-encoding'] = params['ResponseContentEncoding'];
- // 如果用户自己传入了 output
- submitRequest.call(this, {
- Action: 'name/cos:GetObject',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- VersionId: params.VersionId,
- DataType: params.DataType,
- headers: params.Headers,
- qs: reqParams,
- qsStr: reqParamsStr,
- rawBody: true,
- onDownloadProgress: onProgress
- }, function (err, data) {
- onProgress(null, true);
- if (err) {
- var statusCode = err.statusCode;
- if (params.Headers['If-Modified-Since'] && statusCode && statusCode === 304) {
- return callback(null, {
- NotModified: true
- });
- }
- return callback(err);
- }
- callback(null, {
- Body: data.body,
- ETag: util.attr(data.headers, 'etag', ''),
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 上传 object
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key 文件名称,必须
- * @param {File || Blob || String} params.Body 上传文件对象或字符串,必须
- * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须
- * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
- * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
- * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
- * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须
- * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须
- * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须
- * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须
- * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
- * @param {Function} params.onProgress 上传进度回调函数
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 为对应的 object 数据
- * @return {String} data.ETag 为对应上传文件的 ETag 值
- */
- function putObject(params, callback) {
- var self = this;
- var FileSize = params.ContentLength;
- var onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
- // 特殊处理 Cache-Control、Content-Type,避免代理更改这两个字段导致写入到 Object 属性里
- var headers = params.Headers;
- if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
- if (!headers['Content-Type'] && !headers['content-type']) headers['Content-Type'] = params.Body && params.Body.type || '';
- var needCalcMd5 = params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5 || self.options.UploadCheckContentMd5;
- util.getBodyMd5(needCalcMd5, params.Body, function (md5) {
- if (md5) {
- if (self.options.UploadCheckContentMd5) headers['Content-MD5'] = util.binaryBase64(md5);
- if (params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5) headers['x-cos-meta-md5'] = md5;
- }
- if (params.ContentLength !== undefined) headers['Content-Length'] = params.ContentLength;
- onProgress(null, true); // 任务状态开始 uploading
- submitRequest.call(self, {
- Action: 'name/cos:PutObject',
- TaskId: params.TaskId,
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- qs: params.Query,
- body: params.Body,
- onProgress: onProgress
- }, function (err, data) {
- if (err) {
- onProgress(null, true);
- return callback(err);
- }
- onProgress({ loaded: FileSize, total: FileSize }, true);
- var url = getUrl({
- ForcePathStyle: self.options.ForcePathStyle,
- protocol: self.options.Protocol,
- domain: self.options.Domain,
- bucket: params.Bucket,
- region: !self.options.UseAccelerate ? params.Region : 'accelerate',
- object: params.Key
- });
- url = url.substr(url.indexOf('://') + 3);
- data.Location = url;
- data.ETag = util.attr(data.headers, 'etag', '');
- callback(null, data);
- });
- }, params.onHashProgress);
- }
- /**
- * 删除 object
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {Function} callback 回调函数,必须
- * @param {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @param {Object} data 删除操作成功之后返回的数据
- */
- function deleteObject(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteObject',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- VersionId: params.VersionId,
- action: params.Recursive ? 'recursive' : ''
- }, function (err, data) {
- if (err) {
- var statusCode = err.statusCode;
- if (statusCode && statusCode === 404) {
- return callback(null, { BucketNotFound: true, statusCode: statusCode });
- } else {
- return callback(err);
- }
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 object 的 权限列表
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.AccessControlPolicy 权限列表
- */
- function getObjectAcl(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetObjectACL',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- action: 'acl'
- }, function (err, data) {
- if (err) return callback(err);
- var AccessControlPolicy = data.AccessControlPolicy || {};
- var Owner = AccessControlPolicy.Owner || {};
- var Grant = AccessControlPolicy.AccessControlList && AccessControlPolicy.AccessControlList.Grant || [];
- Grant = util.isArray(Grant) ? Grant : [Grant];
- var result = decodeAcl(AccessControlPolicy);
- delete result.GrantWrite;
- if (data.headers && data.headers['x-cos-acl']) {
- result.ACL = data.headers['x-cos-acl'];
- }
- result = util.extend(result, {
- Owner: Owner,
- Grants: Grant,
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- /**
- * 设置 object 的 权限列表
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function putObjectAcl(params, callback) {
- var headers = params.Headers;
- var xml = '';
- if (params['AccessControlPolicy']) {
- var AccessControlPolicy = util.clone(params['AccessControlPolicy'] || {});
- var Grants = AccessControlPolicy.Grants || AccessControlPolicy.Grant;
- Grants = util.isArray(Grants) ? Grants : [Grants];
- delete AccessControlPolicy.Grant;
- delete AccessControlPolicy.Grants;
- AccessControlPolicy.AccessControlList = { Grant: Grants };
- xml = util.json2xml({ AccessControlPolicy: AccessControlPolicy });
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- }
- // Grant Header 去重
- util.each(headers, function (val, key) {
- if (key.indexOf('x-cos-grant-') === 0) {
- headers[key] = uniqGrant(headers[key]);
- }
- });
- submitRequest.call(this, {
- Action: 'name/cos:PutObjectACL',
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- action: 'acl',
- headers: headers,
- body: xml
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * Options Object请求实现跨域访问的预请求。即发出一个 OPTIONS 请求给服务器以确认是否可以进行跨域操作。
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function optionsObject(params, callback) {
- var headers = params.Headers;
- headers['Origin'] = params['Origin'];
- headers['Access-Control-Request-Method'] = params['AccessControlRequestMethod'];
- headers['Access-Control-Request-Headers'] = params['AccessControlRequestHeaders'];
- submitRequest.call(this, {
- Action: 'name/cos:OptionsObject',
- method: 'OPTIONS',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: headers
- }, function (err, data) {
- if (err) {
- if (err.statusCode && err.statusCode === 403) {
- return callback(null, {
- OptionsForbidden: true,
- statusCode: err.statusCode
- });
- }
- return callback(err);
- }
- var headers = data.headers || {};
- callback(null, {
- AccessControlAllowOrigin: headers['access-control-allow-origin'],
- AccessControlAllowMethods: headers['access-control-allow-methods'],
- AccessControlAllowHeaders: headers['access-control-allow-headers'],
- AccessControlExposeHeaders: headers['access-control-expose-headers'],
- AccessControlMaxAge: headers['access-control-max-age'],
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * @param {Object} 参数列表
- * @param {String} Bucket Bucket 名称
- * @param {String} Region 地域名称
- * @param {String} Key 文件名称
- * @param {String} CopySource 源文件URL绝对路径,可以通过versionid子资源指定历史版本
- * @param {String} ACL 允许用户自定义文件权限。有效值:private,public-read默认值:private。
- * @param {String} GrantRead 赋予被授权者读的权限,格式 x-cos-grant-read: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
- * @param {String} GrantWrite 赋予被授权者写的权限,格式 x-cos-grant-write: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
- * @param {String} GrantFullControl 赋予被授权者读写权限,格式 x-cos-grant-full-control: uin=" ",uin=" ",当需要给子账户授权时,uin="RootAcountID/SubAccountID",当需要给根账户授权时,uin="RootAcountID"。
- * @param {String} MetadataDirective 是否拷贝元数据,枚举值:Copy, Replaced,默认值Copy。假如标记为Copy,忽略Header中的用户元数据信息直接复制;假如标记为Replaced,按Header信息修改元数据。当目标路径和原路径一致,即用户试图修改元数据时,必须为Replaced
- * @param {String} CopySourceIfModifiedSince 当Object在指定时间后被修改,则执行操作,否则返回412。可与x-cos-copy-source-If-None-Match一起使用,与其他条件联合使用返回冲突。
- * @param {String} CopySourceIfUnmodifiedSince 当Object在指定时间后未被修改,则执行操作,否则返回412。可与x-cos-copy-source-If-Match一起使用,与其他条件联合使用返回冲突。
- * @param {String} CopySourceIfMatch 当Object的ETag和给定一致时,则执行操作,否则返回412。可与x-cos-copy-source-If-Unmodified-Since一起使用,与其他条件联合使用返回冲突。
- * @param {String} CopySourceIfNoneMatch 当Object的ETag和给定不一致时,则执行操作,否则返回412。可与x-cos-copy-source-If-Modified-Since一起使用,与其他条件联合使用返回冲突。
- * @param {String} StorageClass 存储级别,枚举值:存储级别,枚举值:Standard, Standard_IA,Archive;默认值:Standard
- * @param {String} CacheControl 指定所有缓存机制在整个请求/响应链中必须服从的指令。
- * @param {String} ContentDisposition MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件
- * @param {String} ContentEncoding HTTP 中用来对「采用何种编码格式传输正文」进行协定的一对头部字段
- * @param {String} ContentLength 设置响应消息的实体内容的大小,单位为字节
- * @param {String} ContentType RFC 2616 中定义的 HTTP 请求内容类型(MIME),例如text/plain
- * @param {String} Expect 请求的特定的服务器行为
- * @param {String} Expires 响应过期的日期和时间
- * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
- * @param {String} ContentLanguage 指定内容语言
- * @param {String} x-cos-meta-* 允许用户自定义的头部信息,将作为 Object 元数据返回。大小限制2K。
- */
- function putObjectCopy(params, callback) {
- // 特殊处理 Cache-Control
- var self = this;
- var headers = params.Headers;
- if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
- var CopySource = params.CopySource || '';
- var m = util.getSourceParams.call(this, CopySource);
- if (!m) {
- callback(util.error(new Error('CopySource format error')));
- return;
- }
- var SourceBucket = m[1];
- var SourceRegion = m[3];
- var SourceKey = decodeURIComponent(m[4]);
- submitRequest.call(this, {
- Scope: [{
- action: 'name/cos:GetObject',
- bucket: SourceBucket,
- region: SourceRegion,
- prefix: SourceKey
- }, {
- action: 'name/cos:PutObject',
- bucket: params.Bucket,
- region: params.Region,
- prefix: params.Key
- }],
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- VersionId: params.VersionId,
- headers: params.Headers
- }, function (err, data) {
- if (err) return callback(err);
- var result = util.clone(data.CopyObjectResult || {});
- var url = getUrl({
- ForcePathStyle: self.options.ForcePathStyle,
- protocol: self.options.Protocol,
- domain: self.options.Domain,
- bucket: params.Bucket,
- region: params.Region,
- object: params.Key,
- isLocation: true
- });
- util.extend(result, {
- Location: url,
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- function uploadPartCopy(params, callback) {
- var CopySource = params.CopySource || '';
- var m = util.getSourceParams.call(this, CopySource);
- if (!m) {
- callback(util.error(new Error('CopySource format error')));
- return;
- }
- var SourceBucket = m[1];
- var SourceRegion = m[3];
- var SourceKey = decodeURIComponent(m[4]);
- submitRequest.call(this, {
- Scope: [{
- action: 'name/cos:GetObject',
- bucket: SourceBucket,
- region: SourceRegion,
- prefix: SourceKey
- }, {
- action: 'name/cos:PutObject',
- bucket: params.Bucket,
- region: params.Region,
- prefix: params.Key
- }],
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- VersionId: params.VersionId,
- qs: {
- partNumber: params['PartNumber'],
- uploadId: params['UploadId']
- },
- headers: params.Headers
- }, function (err, data) {
- if (err) return callback(err);
- var result = util.clone(data.CopyPartResult || {});
- util.extend(result, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- function deleteMultipleObject(params, callback) {
- var Objects = params.Objects || [];
- var Quiet = params.Quiet;
- Objects = util.isArray(Objects) ? Objects : [Objects];
- var xml = util.json2xml({ Delete: { Object: Objects, Quiet: Quiet || false } });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- var Scope = util.map(Objects, function (v) {
- return {
- action: 'name/cos:DeleteObject',
- bucket: params.Bucket,
- region: params.Region,
- prefix: v.Key
- };
- });
- submitRequest.call(this, {
- Scope: Scope,
- method: 'POST',
- Bucket: params.Bucket,
- Region: params.Region,
- body: xml,
- action: 'delete',
- headers: headers
- }, function (err, data) {
- if (err) return callback(err);
- var DeleteResult = data.DeleteResult || {};
- var Deleted = DeleteResult.Deleted || [];
- var Errors = DeleteResult.Error || [];
- Deleted = util.isArray(Deleted) ? Deleted : [Deleted];
- Errors = util.isArray(Errors) ? Errors : [Errors];
- var result = util.clone(DeleteResult);
- util.extend(result, {
- Error: Errors,
- Deleted: Deleted,
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- function restoreObject(params, callback) {
- var headers = params.Headers;
- if (!params['RestoreRequest']) {
- callback(util.error(new Error('missing param RestoreRequest')));
- return;
- }
- var RestoreRequest = params.RestoreRequest || {};
- var xml = util.json2xml({ RestoreRequest: RestoreRequest });
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:RestoreObject',
- method: 'POST',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- VersionId: params.VersionId,
- body: xml,
- action: 'restore',
- headers: headers
- }, callback);
- }
- /**
- * 设置 Object 的标签
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Object名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Array} params.TagSet 标签设置,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
- * @return {Object} data 返回数据
- */
- function putObjectTagging(params, callback) {
- var Tagging = params['Tagging'] || {};
- var Tags = Tagging.TagSet || Tagging.Tags || params['Tags'] || [];
- Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
- var xml = util.json2xml({ Tagging: { TagSet: { Tag: Tags } } });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:PutObjectTagging',
- method: 'PUT',
- Bucket: params.Bucket,
- Key: params.Key,
- Region: params.Region,
- body: xml,
- action: 'tagging',
- headers: headers,
- VersionId: params.VersionId
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 获取 Object 的标签设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
- * @return {Object} data 返回数据
- */
- function getObjectTagging(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:GetObjectTagging',
- method: 'GET',
- Key: params.Key,
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- action: 'tagging',
- VersionId: params.VersionId
- }, function (err, data) {
- if (err) {
- if (err.statusCode === 404 && err.error && (err.error === "Not Found" || err.error.Code === 'NoSuchTagSet')) {
- var result = {
- Tags: [],
- statusCode: err.statusCode
- };
- err.headers && (result.headers = err.headers);
- callback(null, result);
- } else {
- callback(err);
- }
- return;
- }
- var Tags = [];
- try {
- Tags = data.Tagging.TagSet.Tag || [];
- } catch (e) {}
- Tags = util.clone(util.isArray(Tags) ? Tags : [Tags]);
- callback(null, {
- Tags: Tags,
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 删除 Object 的 标签设置
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Object名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
- * @return {Object} data 返回的数据
- */
- function deleteObjectTagging(params, callback) {
- submitRequest.call(this, {
- Action: 'name/cos:DeleteObjectTagging',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- action: 'tagging',
- VersionId: params.VersionId
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 使用 SQL 语句从指定对象(CSV 格式或者 JSON 格式)中检索内容
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Object名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {Object} params.SelectRequest 地域名称,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/42998
- * @return {Object} data 返回的数据
- */
- function selectObjectContent(params, callback) {
- var SelectType = params['SelectType'];
- if (!SelectType) return callback(util.error(new Error('missing param SelectType')));
- var SelectRequest = params['SelectRequest'] || {};
- var xml = util.json2xml({ SelectRequest: SelectRequest });
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:GetObject',
- method: 'POST',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- action: 'select',
- qs: {
- 'select-type': params['SelectType']
- },
- VersionId: params.VersionId,
- body: xml,
- DataType: 'arraybuffer',
- rawBody: true
- }, function (err, data) {
- if (err && err.statusCode === 204) {
- return callback(null, { statusCode: err.statusCode });
- } else if (err) {
- return callback(err);
- }
- var result = util.parseSelectPayload(data.body);
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers,
- Body: result.body,
- Payload: result.payload
- });
- });
- }
- // 分块上传
- /**
- * 初始化分块上传
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {String} params.UploadId object名称,必须
- * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存 ,非必须
- * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
- * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
- * @param {String} params.ACL 允许用户自定义文件权限,非必须
- * @param {String} params.GrantRead 赋予被授权者读的权限 ,非必须
- * @param {String} params.GrantWrite 赋予被授权者写的权限 ,非必须
- * @param {String} params.GrantFullControl 赋予被授权者读写权限 ,非必须
- * @param {String} params.StorageClass 设置Object的存储级别,枚举值:Standard,Standard_IA,Archive,非必须
- * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function multipartInit(params, callback) {
- var self = this;
- // 特殊处理 Cache-Control
- var headers = params.Headers;
- // 特殊处理 Cache-Control、Content-Type
- if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
- if (!headers['Content-Type'] && !headers['content-type']) headers['Content-Type'] = params.Body && params.Body.type || '';
- util.getBodyMd5(params.Body && (params.UploadAddMetaMd5 || self.options.UploadAddMetaMd5), params.Body, function (md5) {
- if (md5) params.Headers['x-cos-meta-md5'] = md5;
- submitRequest.call(self, {
- Action: 'name/cos:InitiateMultipartUpload',
- method: 'POST',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- action: 'uploads',
- headers: params.Headers,
- qs: params.Query
- }, function (err, data) {
- if (err) return callback(err);
- data = util.clone(data || {});
- if (data && data.InitiateMultipartUploadResult) {
- return callback(null, util.extend(data.InitiateMultipartUploadResult, {
- statusCode: data.statusCode,
- headers: data.headers
- }));
- }
- callback(null, data);
- });
- }, params.onHashProgress);
- }
- /**
- * 分块上传
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {File || Blob || String} params.Body 上传文件对象或字符串
- * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),非必须
- * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
- * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
- * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验值,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.ETag 返回的文件分块 sha1 值
- */
- function multipartUpload(params, callback) {
- var self = this;
- util.getFileSize('multipartUpload', params, function () {
- util.getBodyMd5(self.options.UploadCheckContentMd5, params.Body, function (md5) {
- if (md5) params.Headers['Content-MD5'] = util.binaryBase64(md5);
- submitRequest.call(self, {
- Action: 'name/cos:UploadPart',
- TaskId: params.TaskId,
- method: 'PUT',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- qs: {
- partNumber: params['PartNumber'],
- uploadId: params['UploadId']
- },
- headers: params.Headers,
- onProgress: params.onProgress,
- body: params.Body || null
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, {
- ETag: util.attr(data.headers, 'etag', ''),
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- });
- });
- }
- /**
- * 完成分块上传
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {Array} params.Parts 分块信息列表,必须
- * @param {String} params.Parts[i].PartNumber 块编号,必须
- * @param {String} params.Parts[i].ETag 分块的 sha1 校验值
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.CompleteMultipartUpload 完成分块上传后的文件信息,包括Location, Bucket, Key 和 ETag
- */
- function multipartComplete(params, callback) {
- var self = this;
- var UploadId = params.UploadId;
- var Parts = params['Parts'];
- for (var i = 0, len = Parts.length; i < len; i++) {
- if (Parts[i]['ETag'] && Parts[i]['ETag'].indexOf('"') === 0) {
- continue;
- }
- Parts[i]['ETag'] = '"' + Parts[i]['ETag'] + '"';
- }
- var xml = util.json2xml({ CompleteMultipartUpload: { Part: Parts } });
- // CSP/ceph CompleteMultipartUpload 接口 body 写死了限制 1MB,这里醉倒 10000 片时,xml 字符串去掉空格853KB
- xml = xml.replace(/\n\s*/g, '');
- var headers = params.Headers;
- headers['Content-Type'] = 'application/xml';
- headers['Content-MD5'] = util.binaryBase64(util.md5(xml));
- submitRequest.call(this, {
- Action: 'name/cos:CompleteMultipartUpload',
- method: 'POST',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- qs: {
- uploadId: UploadId
- },
- body: xml,
- headers: headers
- }, function (err, data) {
- if (err) return callback(err);
- var url = getUrl({
- ForcePathStyle: self.options.ForcePathStyle,
- protocol: self.options.Protocol,
- domain: self.options.Domain,
- bucket: params.Bucket,
- region: params.Region,
- object: params.Key,
- isLocation: true
- });
- var res = data.CompleteMultipartUploadResult || {};
- if (res.ProcessResults) {
- if (res && res.ProcessResults) {
- res.UploadResult = {
- OriginalInfo: {
- Key: res.Key,
- Location: url,
- ETag: res.ETag,
- ImageInfo: res.ImageInfo
- },
- ProcessResults: res.ProcessResults
- };
- delete res.ImageInfo;
- delete res.ProcessResults;
- }
- }
- var result = util.extend(res, {
- Location: url,
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- /**
- * 分块上传任务列表查询
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Delimiter 定界符为一个符号,如果有Prefix,则将Prefix到delimiter之间的相同路径归为一类,定义为Common Prefix,然后列出所有Common Prefix。如果没有Prefix,则从路径起点开始,非必须
- * @param {String} params.EncodingType 规定返回值的编码方式,非必须
- * @param {String} params.Prefix 前缀匹配,用来规定返回的文件前缀地址,非必须
- * @param {String} params.MaxUploads 单次返回最大的条目数量,默认1000,非必须
- * @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的条目将被列出,非必须
- * @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的条目将被列出,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.ListMultipartUploadsResult 分块上传任务信息
- */
- function multipartList(params, callback) {
- var reqParams = {};
- reqParams['delimiter'] = params['Delimiter'];
- reqParams['encoding-type'] = params['EncodingType'];
- reqParams['prefix'] = params['Prefix'] || '';
- reqParams['max-uploads'] = params['MaxUploads'];
- reqParams['key-marker'] = params['KeyMarker'];
- reqParams['upload-id-marker'] = params['UploadIdMarker'];
- reqParams = util.clearKey(reqParams);
- submitRequest.call(this, {
- Action: 'name/cos:ListMultipartUploads',
- ResourceKey: reqParams['prefix'],
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- headers: params.Headers,
- qs: reqParams,
- action: 'uploads'
- }, function (err, data) {
- if (err) return callback(err);
- if (data && data.ListMultipartUploadsResult) {
- var Upload = data.ListMultipartUploadsResult.Upload || [];
- Upload = util.isArray(Upload) ? Upload : [Upload];
- data.ListMultipartUploadsResult.Upload = Upload;
- }
- var result = util.clone(data.ListMultipartUploadsResult || {});
- util.extend(result, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- /**
- * 上传的分块列表查询
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {String} params.UploadId 标示本次分块上传的ID,必须
- * @param {String} params.EncodingType 规定返回值的编码方式,非必须
- * @param {String} params.MaxParts 单次返回最大的条目数量,默认1000,非必须
- * @param {String} params.PartNumberMarker 默认以UTF-8二进制顺序列出条目,所有列出条目从marker开始,非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- * @return {Object} data.ListMultipartUploadsResult 分块信息
- */
- function multipartListPart(params, callback) {
- var reqParams = {};
- reqParams['uploadId'] = params['UploadId'];
- reqParams['encoding-type'] = params['EncodingType'];
- reqParams['max-parts'] = params['MaxParts'];
- reqParams['part-number-marker'] = params['PartNumberMarker'];
- submitRequest.call(this, {
- Action: 'name/cos:ListParts',
- method: 'GET',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- qs: reqParams
- }, function (err, data) {
- if (err) return callback(err);
- var ListPartsResult = data.ListPartsResult || {};
- var Part = ListPartsResult.Part || [];
- Part = util.isArray(Part) ? Part : [Part];
- ListPartsResult.Part = Part;
- var result = util.clone(ListPartsResult);
- util.extend(result, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- callback(null, result);
- });
- }
- /**
- * 抛弃分块上传
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {String} params.UploadId 标示本次分块上传的ID,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function multipartAbort(params, callback) {
- var reqParams = {};
- reqParams['uploadId'] = params['UploadId'];
- submitRequest.call(this, {
- Action: 'name/cos:AbortMultipartUpload',
- method: 'DELETE',
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- headers: params.Headers,
- qs: reqParams
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, {
- statusCode: data.statusCode,
- headers: data.headers
- });
- });
- }
- /**
- * 抛弃分块上传
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {String} params.UploadId 标示本次分块上传的ID,必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function request(params, callback) {
- submitRequest.call(this, {
- method: params.Method,
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- action: params.Action,
- headers: params.Headers,
- qs: params.Query,
- body: params.Body,
- Url: params.Url,
- rawBody: params.RawBody,
- DataType: params.DataType
- }, function (err, data) {
- if (err) return callback(err);
- if (data && data.body) {
- data.Body = data.body;
- delete data.body;
- }
- callback(err, data);
- });
- }
- /**
- * 追加上传
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {File || Blob || String} params.Body 上传文件对象或字符串
- * @param {Number} params.Position 追加操作的起始点,单位为字节,必须
- * @param {String} params.CacheControl RFC 2616 中定义的缓存策略,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentDisposition RFC 2616 中定义的文件名称,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentEncoding RFC 2616 中定义的编码格式,将作为 Object 元数据保存,非必须
- * @param {String} params.ContentLength RFC 2616 中定义的 HTTP 请求内容长度(字节),必须
- * @param {String} params.ContentType RFC 2616 中定义的内容类型(MIME),将作为 Object 元数据保存,非必须
- * @param {String} params.Expect 当使用 Expect: 100-continue 时,在收到服务端确认后,才会发送请求内容,非必须
- * @param {String} params.Expires RFC 2616 中定义的过期时间,将作为 Object 元数据保存,非必须
- * @param {String} params.ACL 允许用户自定义文件权限,有效值:private | public-read,非必须
- * @param {String} params.GrantRead 赋予被授权者读取对象的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.GrantReadAcp 赋予被授权者读取对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.GrantWriteAcp 赋予被授权者写入对象的访问控制列表(ACL)的权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.GrantFullControl 赋予被授权者操作对象的所有权限,格式:id="[OwnerUin]",可使用半角逗号(,)分隔多组被授权者,非必须
- * @param {String} params.StorageClass 设置对象的存储级别,枚举值:STANDARD、STANDARD_IA、ARCHIVE,默认值:STANDARD,非必须
- * @param {String} params.x-cos-meta-* 允许用户自定义的头部信息,将作为对象的元数据保存。大小限制2KB,非必须
- * @param {String} params.ContentSha1 RFC 3174 中定义的 160-bit 内容 SHA-1 算法校验,非必须
- * @param {String} params.ServerSideEncryption 支持按照指定的加密算法进行服务端数据加密,格式 x-cos-server-side-encryption: "AES256",非必须
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function appendObject(params, callback) {
- // 特殊处理 Cache-Control、Content-Type,避免代理更改这两个字段导致写入到 Object 属性里
- var headers = params.Headers;
- if (!headers['Cache-Control'] && !headers['cache-control']) headers['Cache-Control'] = '';
- if (!headers['Content-Type'] && !headers['content-type']) headers['Content-Type'] = params.Body && params.Body.type || '';
- submitRequest.call(this, {
- Action: 'name/cos:AppendObject',
- method: 'POST',
- Bucket: params.Bucket,
- Region: params.Region,
- action: 'append',
- Key: params.Key,
- body: params.Body,
- qs: {
- position: params.Position
- },
- headers: params.Headers
- }, function (err, data) {
- if (err) return callback(err);
- callback(null, data);
- });
- }
- /**
- * 获取签名
- * @param {Object} params 参数对象,必须
- * @param {String} params.Method 请求方法,必须
- * @param {String} params.Key object名称,必须
- * @param {String} params.Expires 名超时时间,单位秒,可选
- * @return {String} data 返回签名字符串
- */
- function getAuth(params) {
- var self = this;
- return util.getAuth({
- SecretId: params.SecretId || this.options.SecretId || '',
- SecretKey: params.SecretKey || this.options.SecretKey || '',
- Bucket: params.Bucket,
- Region: params.Region,
- Method: params.Method,
- Key: params.Key,
- Query: params.Query,
- Headers: params.Headers,
- Expires: params.Expires,
- UseRawKey: self.options.UseRawKey,
- SystemClockOffset: self.options.SystemClockOffset
- });
- }
- /**
- * 获取文件下载链接
- * @param {Object} params 参数对象,必须
- * @param {String} params.Bucket Bucket名称,必须
- * @param {String} params.Region 地域名称,必须
- * @param {String} params.Key object名称,必须
- * @param {String} params.Method 请求的方法,可选
- * @param {String} params.Expires 签名超时时间,单位秒,可选
- * @param {Function} callback 回调函数,必须
- * @return {Object} err 请求失败的错误,如果请求成功,则为空。https://cloud.tencent.com/document/product/436/7730
- * @return {Object} data 返回的数据
- */
- function getObjectUrl(params, callback) {
- var self = this;
- var useAccelerate = params.UseAccelerate === undefined ? self.options.UseAccelerate : params.UseAccelerate;
- var url = getUrl({
- ForcePathStyle: self.options.ForcePathStyle,
- protocol: params.Protocol || self.options.Protocol,
- domain: params.Domain || self.options.Domain,
- bucket: params.Bucket,
- region: useAccelerate ? 'accelerate' : params.Region,
- object: params.Key
- });
- var queryParamsStr = '';
- if (params.Query) {
- queryParamsStr += util.obj2str(params.Query);
- }
- if (params.QueryString) {
- queryParamsStr += (queryParamsStr ? '&' : '') + params.QueryString;
- }
- var syncUrl = url;
- if (params.Sign !== undefined && !params.Sign) {
- queryParamsStr && (syncUrl += '?' + queryParamsStr);
- callback(null, { Url: syncUrl });
- return syncUrl;
- }
- // 签名加上 Host,避免跨桶访问
- var SignHost = getSignHost.call(this, { Bucket: params.Bucket, Region: params.Region, UseAccelerate: params.UseAccelerate, Url: url });
- var AuthData = getAuthorizationAsync.call(this, {
- Action: (params.Method || '').toUpperCase() === 'PUT' ? 'name/cos:PutObject' : 'name/cos:GetObject',
- Bucket: params.Bucket || '',
- Region: params.Region || '',
- Method: params.Method || 'get',
- Key: params.Key,
- Expires: params.Expires,
- Headers: params.Headers,
- Query: params.Query,
- SignHost: SignHost,
- ForceSignHost: params.ForceSignHost === false ? false : self.options.ForceSignHost // getObjectUrl支持传参ForceSignHost
- }, function (err, AuthData) {
- if (!callback) return;
- if (err) {
- callback(err);
- return;
- }
- // 兼容万象url qUrlParamList需要再encode一次
- var replaceUrlParamList = function (url) {
- var urlParams = url.match(/q-url-param-list.*?(?=&)/g)[0];
- var encodedParams = 'q-url-param-list=' + encodeURIComponent(urlParams.replace(/q-url-param-list=/, '')).toLowerCase();
- var reg = new RegExp(urlParams, 'g');
- var replacedUrl = url.replace(reg, encodedParams);
- return replacedUrl;
- };
- var signUrl = url;
- signUrl += '?' + (AuthData.Authorization.indexOf('q-signature') > -1 ? replaceUrlParamList(AuthData.Authorization) : 'sign=' + encodeURIComponent(AuthData.Authorization));
- AuthData.SecurityToken && (signUrl += '&x-cos-security-token=' + AuthData.SecurityToken);
- AuthData.ClientIP && (signUrl += '&clientIP=' + AuthData.ClientIP);
- AuthData.ClientUA && (signUrl += '&clientUA=' + AuthData.ClientUA);
- AuthData.Token && (signUrl += '&token=' + AuthData.Token);
- queryParamsStr && (signUrl += '&' + queryParamsStr);
- setTimeout(function () {
- callback(null, { Url: signUrl });
- });
- });
- if (AuthData) {
- syncUrl += '?' + AuthData.Authorization + (AuthData.SecurityToken ? '&x-cos-security-token=' + AuthData.SecurityToken : '');
- queryParamsStr && (syncUrl += '&' + queryParamsStr);
- } else {
- queryParamsStr && (syncUrl += '?' + queryParamsStr);
- }
- return syncUrl;
- }
- /**
- * 私有方法
- */
- function decodeAcl(AccessControlPolicy) {
- var result = {
- GrantFullControl: [],
- GrantWrite: [],
- GrantRead: [],
- GrantReadAcp: [],
- GrantWriteAcp: [],
- ACL: ''
- };
- var GrantMap = {
- 'FULL_CONTROL': 'GrantFullControl',
- 'WRITE': 'GrantWrite',
- 'READ': 'GrantRead',
- 'READ_ACP': 'GrantReadAcp',
- 'WRITE_ACP': 'GrantWriteAcp'
- };
- var AccessControlList = AccessControlPolicy && AccessControlPolicy.AccessControlList || {};
- var Grant = AccessControlList.Grant;
- if (Grant) {
- Grant = util.isArray(Grant) ? Grant : [Grant];
- }
- var PublicAcl = { READ: 0, WRITE: 0, FULL_CONTROL: 0 };
- Grant && Grant.length && util.each(Grant, function (item) {
- if (item.Grantee.ID === 'qcs::cam::anyone:anyone' || item.Grantee.URI === 'http://cam.qcloud.com/groups/global/AllUsers') {
- PublicAcl[item.Permission] = 1;
- } else if (item.Grantee.ID !== AccessControlPolicy.Owner.ID) {
- result[GrantMap[item.Permission]].push('id="' + item.Grantee.ID + '"');
- }
- });
- if (PublicAcl.FULL_CONTROL || PublicAcl.WRITE && PublicAcl.READ) {
- result.ACL = 'public-read-write';
- } else if (PublicAcl.READ) {
- result.ACL = 'public-read';
- } else {
- result.ACL = 'private';
- }
- util.each(GrantMap, function (item) {
- result[item] = uniqGrant(result[item].join(','));
- });
- return result;
- }
- // Grant 去重
- function uniqGrant(str) {
- var arr = str.split(',');
- var exist = {};
- var i, item;
- for (i = 0; i < arr.length;) {
- item = arr[i].trim();
- if (exist[item]) {
- arr.splice(i, 1);
- } else {
- exist[item] = true;
- arr[i] = item;
- i++;
- }
- }
- return arr.join(',');
- }
- // 生成操作 url
- function getUrl(params) {
- var region = params.region || '';
- var longBucket = params.bucket || '';
- var shortBucket = longBucket.substr(0, longBucket.lastIndexOf('-'));
- var appId = longBucket.substr(longBucket.lastIndexOf('-') + 1);
- var domain = params.domain;
- var object = params.object;
- if (typeof domain === 'function') {
- domain = domain({ Bucket: longBucket, Region: region });
- }
- var protocol = params.protocol || (util.isBrowser && location.protocol === 'http:' ? 'http:' : 'https:');
- if (!domain) {
- if (['cn-south', 'cn-south-2', 'cn-north', 'cn-east', 'cn-southwest', 'sg'].indexOf(region) > -1) {
- domain = '{Region}.myqcloud.com';
- } else {
- domain = 'cos.{Region}.myqcloud.com';
- }
- if (!params.ForcePathStyle) {
- domain = '{Bucket}.' + domain;
- }
- }
- domain = domain.replace(/\{\{AppId\}\}/ig, appId).replace(/\{\{Bucket\}\}/ig, shortBucket).replace(/\{\{Region\}\}/ig, region).replace(/\{\{.*?\}\}/ig, '');
- domain = domain.replace(/\{AppId\}/ig, appId).replace(/\{BucketName\}/ig, shortBucket).replace(/\{Bucket\}/ig, longBucket).replace(/\{Region\}/ig, region).replace(/\{.*?\}/ig, '');
- if (!/^[a-zA-Z]+:\/\//.test(domain)) {
- domain = protocol + '//' + domain;
- }
- // 去掉域名最后的斜杆
- if (domain.slice(-1) === '/') {
- domain = domain.slice(0, -1);
- }
- var url = domain;
- if (params.ForcePathStyle) {
- url += '/' + longBucket;
- }
- url += '/';
- if (object) {
- url += util.camSafeUrlEncode(object).replace(/%2F/g, '/');
- }
- if (params.isLocation) {
- url = url.replace(/^https?:\/\//, '');
- }
- return url;
- }
- var getSignHost = function (opt) {
- if (!opt.Bucket || !opt.Region) return '';
- var useAccelerate = opt.UseAccelerate === undefined ? this.options.UseAccelerate : opt.UseAccelerate;
- var url = opt.Url || getUrl({
- ForcePathStyle: this.options.ForcePathStyle,
- protocol: this.options.Protocol,
- domain: this.options.Domain,
- bucket: opt.Bucket,
- region: useAccelerate ? 'accelerate' : opt.Region
- });
- var urlHost = url.replace(/^https?:\/\/([^/]+)(\/.*)?$/, '$1');
- var standardHostReg = new RegExp('^([a-z\\d-]+-\\d+\\.)?(cos|cosv6|ci|pic)\\.([a-z\\d-]+)\\.myqcloud\\.com$');
- if (standardHostReg.test(urlHost)) return urlHost;
- return '';
- };
- // 异步获取签名
- function getAuthorizationAsync(params, callback) {
- var headers = util.clone(params.Headers);
- var headerHost = '';
- util.each(headers, function (v, k) {
- (v === '' || ['content-type', 'cache-control', 'expires'].indexOf(k.toLowerCase()) > -1) && delete headers[k];
- if (k.toLowerCase() === 'host') headerHost = v;
- });
- // ForceSignHost明确传入false才不加入host签名
- var forceSignHost = params.ForceSignHost === false ? false : true;
- // Host 加入签名计算
- if (!headerHost && params.SignHost && forceSignHost) headers.Host = params.SignHost;
- // 获取凭证的回调,避免用户 callback 多次
- var cbDone = false;
- var cb = function (err, AuthData) {
- if (cbDone) return;
- cbDone = true;
- if (AuthData && AuthData.XCosSecurityToken && !AuthData.SecurityToken) {
- AuthData = util.clone(AuthData);
- AuthData.SecurityToken = AuthData.XCosSecurityToken;
- delete AuthData.XCosSecurityToken;
- }
- callback && callback(err, AuthData);
- };
- var self = this;
- var Bucket = params.Bucket || '';
- var Region = params.Region || '';
- // PathName
- var KeyName = params.Key || '';
- if (self.options.ForcePathStyle && Bucket) {
- KeyName = Bucket + '/' + KeyName;
- }
- var Pathname = '/' + KeyName;
- // Action、ResourceKey
- var StsData = {};
- var Scope = params.Scope;
- if (!Scope) {
- var Action = params.Action || '';
- var ResourceKey = params.ResourceKey || params.Key || '';
- Scope = params.Scope || [{
- action: Action,
- bucket: Bucket,
- region: Region,
- prefix: ResourceKey
- }];
- }
- var ScopeKey = util.md5(JSON.stringify(Scope));
- // STS
- self._StsCache = self._StsCache || [];
- (function () {
- var i, AuthData;
- for (i = self._StsCache.length - 1; i >= 0; i--) {
- AuthData = self._StsCache[i];
- var compareTime = Math.round(util.getSkewTime(self.options.SystemClockOffset) / 1000) + 30;
- if (AuthData.StartTime && compareTime < AuthData.StartTime || compareTime >= AuthData.ExpiredTime) {
- self._StsCache.splice(i, 1);
- continue;
- }
- if (!AuthData.ScopeLimit || AuthData.ScopeLimit && AuthData.ScopeKey === ScopeKey) {
- StsData = AuthData;
- break;
- }
- }
- })();
- var calcAuthByTmpKey = function () {
- var KeyTime = '';
- if (StsData.StartTime && params.Expires) KeyTime = StsData.StartTime + ';' + (StsData.StartTime + params.Expires * 1);else if (StsData.StartTime && StsData.ExpiredTime) KeyTime = StsData.StartTime + ';' + StsData.ExpiredTime;
- var Authorization = util.getAuth({
- SecretId: StsData.TmpSecretId,
- SecretKey: StsData.TmpSecretKey,
- Method: params.Method,
- Pathname: Pathname,
- Query: params.Query,
- Headers: headers,
- Expires: params.Expires,
- UseRawKey: self.options.UseRawKey,
- SystemClockOffset: self.options.SystemClockOffset,
- KeyTime: KeyTime,
- ForceSignHost: forceSignHost
- });
- var AuthData = {
- Authorization: Authorization,
- SecurityToken: StsData.SecurityToken || StsData.XCosSecurityToken || '',
- Token: StsData.Token || '',
- ClientIP: StsData.ClientIP || '',
- ClientUA: StsData.ClientUA || ''
- };
- cb(null, AuthData);
- };
- var checkAuthError = function (AuthData) {
- if (AuthData.Authorization) {
- // 检查签名格式
- var formatAllow = false;
- var auth = AuthData.Authorization;
- if (auth) {
- if (auth.indexOf(' ') > -1) {
- formatAllow = false;
- } 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) {
- formatAllow = true;
- } else {
- try {
- auth = atob(auth);
- if (auth.indexOf('a=') > -1 && auth.indexOf('k=') > -1 && auth.indexOf('t=') > -1 && auth.indexOf('r=') > -1 && auth.indexOf('b=') > -1) {
- formatAllow = true;
- }
- } catch (e) {}
- }
- }
- if (!formatAllow) return util.error(new Error('getAuthorization callback params format error'));
- } else {
- if (!AuthData.TmpSecretId) return util.error(new Error('getAuthorization callback params missing "TmpSecretId"'));
- if (!AuthData.TmpSecretKey) return util.error(new Error('getAuthorization callback params missing "TmpSecretKey"'));
- if (!AuthData.SecurityToken && !AuthData.XCosSecurityToken) return util.error(new Error('getAuthorization callback params missing "SecurityToken"'));
- if (!AuthData.ExpiredTime) return util.error(new Error('getAuthorization callback params missing "ExpiredTime"'));
- if (AuthData.ExpiredTime && AuthData.ExpiredTime.toString().length !== 10) return util.error(new Error('getAuthorization callback params "ExpiredTime" should be 10 digits'));
- if (AuthData.StartTime && AuthData.StartTime.toString().length !== 10) return util.error(new Error('getAuthorization callback params "StartTime" should be 10 StartTime'));
- }
- return false;
- };
- // 先判断是否有临时密钥
- if (StsData.ExpiredTime && StsData.ExpiredTime - util.getSkewTime(self.options.SystemClockOffset) / 1000 > 60) {
- // 如果缓存的临时密钥有效,并还有超过60秒有效期就直接使用
- calcAuthByTmpKey();
- } else if (self.options.getAuthorization) {
- // 外部计算签名或获取临时密钥
- self.options.getAuthorization.call(self, {
- Bucket: Bucket,
- Region: Region,
- Method: params.Method,
- Key: KeyName,
- Pathname: Pathname,
- Query: params.Query,
- Headers: headers,
- Scope: Scope,
- SystemClockOffset: self.options.SystemClockOffset,
- ForceSignHost: forceSignHost
- }, function (AuthData) {
- if (typeof AuthData === 'string') AuthData = { Authorization: AuthData };
- var AuthError = checkAuthError(AuthData);
- if (AuthError) return cb(AuthError);
- if (AuthData.Authorization) {
- cb(null, AuthData);
- } else {
- StsData = AuthData || {};
- StsData.Scope = Scope;
- StsData.ScopeKey = ScopeKey;
- self._StsCache.push(StsData);
- calcAuthByTmpKey();
- }
- });
- } else if (self.options.getSTS) {
- // 外部获取临时密钥
- self.options.getSTS.call(self, {
- Bucket: Bucket,
- Region: Region
- }, function (data) {
- StsData = data || {};
- StsData.Scope = Scope;
- StsData.ScopeKey = ScopeKey;
- if (!StsData.TmpSecretId) StsData.TmpSecretId = StsData.SecretId;
- if (!StsData.TmpSecretKey) StsData.TmpSecretKey = StsData.SecretKey;
- var AuthError = checkAuthError(StsData);
- if (AuthError) return cb(AuthError);
- self._StsCache.push(StsData);
- calcAuthByTmpKey();
- });
- } else {
- // 内部计算获取签名
- return function () {
- var Authorization = util.getAuth({
- SecretId: params.SecretId || self.options.SecretId,
- SecretKey: params.SecretKey || self.options.SecretKey,
- Method: params.Method,
- Pathname: Pathname,
- Query: params.Query,
- Headers: headers,
- Expires: params.Expires,
- UseRawKey: self.options.UseRawKey,
- SystemClockOffset: self.options.SystemClockOffset,
- ForceSignHost: forceSignHost
- });
- var AuthData = {
- Authorization: Authorization,
- SecurityToken: self.options.SecurityToken || self.options.XCosSecurityToken
- };
- cb(null, AuthData);
- return AuthData;
- }();
- }
- return '';
- }
- // 调整时间偏差
- function allowRetry(err) {
- var allowRetry = false;
- var isTimeError = false;
- var serverDate = err.headers && (err.headers.date || err.headers.Date) || err.error && err.error.ServerTime;
- try {
- var errorCode = err.error.Code;
- var errorMessage = err.error.Message;
- if (errorCode === 'RequestTimeTooSkewed' || errorCode === 'AccessDenied' && errorMessage === 'Request has expired') {
- isTimeError = true;
- }
- } catch (e) {}
- if (err) {
- if (isTimeError && serverDate) {
- var serverTime = Date.parse(serverDate);
- if (this.options.CorrectClockSkew && Math.abs(util.getSkewTime(this.options.SystemClockOffset) - serverTime) >= 30000) {
- console.error('error: Local time is too skewed.');
- this.options.SystemClockOffset = serverTime - Date.now();
- allowRetry = true;
- }
- } else if (Math.floor(err.statusCode / 100) === 5) {
- allowRetry = true;
- }
- }
- return allowRetry;
- }
- // 获取签名并发起请求
- function submitRequest(params, callback) {
- var self = this;
- // 处理 headers
- !params.headers && (params.headers = {});
- // 处理 query
- !params.qs && (params.qs = {});
- params.VersionId && (params.qs.versionId = params.VersionId);
- params.qs = util.clearKey(params.qs);
- // 清理 undefined 和 null 字段
- params.headers && (params.headers = util.clearKey(params.headers));
- params.qs && (params.qs = util.clearKey(params.qs));
- var Query = util.clone(params.qs);
- params.action && (Query[params.action] = '');
- var paramsUrl = params.url || params.Url;
- var SignHost = params.SignHost || getSignHost.call(this, { Bucket: params.Bucket, Region: params.Region, Url: paramsUrl });
- var next = function (tryTimes) {
- var oldClockOffset = self.options.SystemClockOffset;
- getAuthorizationAsync.call(self, {
- Bucket: params.Bucket || '',
- Region: params.Region || '',
- Method: params.method,
- Key: params.Key,
- Query: Query,
- Headers: params.headers,
- SignHost: SignHost,
- Action: params.Action,
- ResourceKey: params.ResourceKey,
- Scope: params.Scope,
- ForceSignHost: self.options.ForceSignHost
- }, function (err, AuthData) {
- if (err) {
- callback(err);
- return;
- }
- params.AuthData = AuthData;
- _submitRequest.call(self, params, function (err, data) {
- if (err && tryTimes < 2 && (oldClockOffset !== self.options.SystemClockOffset || allowRetry.call(self, err))) {
- if (params.headers) {
- delete params.headers.Authorization;
- delete params.headers['token'];
- delete params.headers['clientIP'];
- delete params.headers['clientUA'];
- params.headers['x-cos-security-token'] && delete params.headers['x-cos-security-token'];
- params.headers['x-ci-security-token'] && delete params.headers['x-ci-security-token'];
- }
- next(tryTimes + 1);
- } else {
- callback(err, data);
- }
- });
- });
- };
- next(1);
- }
- // 发起请求
- function _submitRequest(params, callback) {
- var self = this;
- var TaskId = params.TaskId;
- if (TaskId && !self._isRunningTask(TaskId)) return;
- var bucket = params.Bucket;
- var region = params.Region;
- var object = params.Key;
- var method = params.method || 'GET';
- var url = params.Url || params.url;
- var body = params.body;
- var rawBody = params.rawBody;
- // url
- if (self.options.UseAccelerate) {
- region = 'accelerate';
- }
- url = url || getUrl({
- ForcePathStyle: self.options.ForcePathStyle,
- protocol: self.options.Protocol,
- domain: self.options.Domain,
- bucket: bucket,
- region: region,
- object: object
- });
- if (params.action) {
- url = url + '?' + params.action;
- }
- if (params.qsStr) {
- if (url.indexOf('?') > -1) {
- url = url + '&' + params.qsStr;
- } else {
- url = url + '?' + params.qsStr;
- }
- }
- var opt = {
- method: method,
- url: url,
- headers: params.headers,
- qs: params.qs,
- body: body
- };
- // 兼容ci接口
- var token = 'x-cos-security-token';
- if (util.isCIHost(url)) {
- token = 'x-ci-security-token';
- }
- // 获取签名
- opt.headers.Authorization = params.AuthData.Authorization;
- params.AuthData.Token && (opt.headers['token'] = params.AuthData.Token);
- params.AuthData.ClientIP && (opt.headers['clientIP'] = params.AuthData.ClientIP);
- params.AuthData.ClientUA && (opt.headers['clientUA'] = params.AuthData.ClientUA);
- params.AuthData.SecurityToken && (opt.headers[token] = params.AuthData.SecurityToken);
- // 清理 undefined 和 null 字段
- opt.headers && (opt.headers = util.clearKey(opt.headers));
- opt = util.clearKey(opt);
- // progress
- if (params.onProgress && typeof params.onProgress === 'function') {
- var contentLength = body && (body.size || body.length) || 0;
- opt.onProgress = function (e) {
- if (TaskId && !self._isRunningTask(TaskId)) return;
- var loaded = e ? e.loaded : 0;
- params.onProgress({ loaded: loaded, total: contentLength });
- };
- }
- if (params.onDownloadProgress) {
- opt.onDownloadProgress = params.onDownloadProgress;
- }
- if (params.DataType) {
- opt.dataType = params.DataType;
- }
- if (this.options.Timeout) {
- opt.timeout = this.options.Timeout;
- }
- self.options.ForcePathStyle && (opt.pathStyle = self.options.ForcePathStyle);
- self.emit('before-send', opt);
- var sender = (self.options.Request || REQUEST)(opt, function (r) {
- if (r.error === 'abort') return;
- var receive = {
- options: opt,
- error: err,
- statusCode: response && response.statusCode || 0,
- headers: response && response.headers || {},
- body: body
- };
- self.emit('after-receive', receive);
- err = receive.error;
- body = receive.body;
- response = {
- statusCode: receive.statusCode,
- headers: receive.headers
- };
- // 抛出事件,允许修改返回值的 error、statusCode、statusMessage、body
- self.emit('after-receive', r);
- var response = { statusCode: r.statusCode, statusMessage: r.statusMessage, headers: r.headers };
- var err = r.error;
- var body = r.body;
- // 返回内容添加 状态码 和 headers
- var hasReturned;
- var cb = function (err, data) {
- TaskId && self.off('inner-kill-task', killTask);
- if (hasReturned) return;
- hasReturned = true;
- var attrs = {};
- response && response.statusCode && (attrs.statusCode = response.statusCode);
- response && response.headers && (attrs.headers = response.headers);
- if (err) {
- err = util.extend(err || {}, attrs);
- callback(err, null);
- } else {
- data = util.extend(data || {}, attrs);
- callback(null, data);
- }
- sender = null;
- };
- // 请求错误,发生网络错误
- if (err) return cb(util.error(err));
- // 请求返回码不为 200
- var statusCode = response.statusCode;
- var statusSuccess = Math.floor(statusCode / 100) === 2; // 200 202 204 206
- // 不对 body 进行转换,body 直接挂载返回
- if (rawBody && statusSuccess) return cb(null, { body: body });
- // 解析 xml body
- var json;
- try {
- json = body && body.indexOf('<') > -1 && body.indexOf('>') > -1 && util.xml2json(body) || {};
- } catch (e) {
- json = {};
- }
- // 处理返回值
- var xmlError = json && json.Error;
- if (statusSuccess) {
- // 正确返回,状态码 2xx 时,body 不会有 Error
- cb(null, json);
- } else if (xmlError) {
- // 正常返回了 xml body,且有 Error 节点
- cb(util.error(new Error(xmlError.Message), { code: xmlError.Code, error: xmlError }));
- } else if (statusCode) {
- // 有错误的状态码
- cb(util.error(new Error(response.statusMessage), { code: '' + statusCode }));
- } else if (statusCode) {
- // 无状态码,或者获取不到状态码
- cb(util.error(new Error('statusCode error')));
- }
- });
- // kill task
- var killTask = function (data) {
- if (data.TaskId === TaskId) {
- sender && sender.abort && sender.abort();
- self.off('inner-kill-task', killTask);
- }
- };
- TaskId && self.on('inner-kill-task', killTask);
- }
- var API_MAP = {
- // Bucket 相关方法
- getService: getService, // Bucket
- putBucket: putBucket,
- headBucket: headBucket, // Bucket
- getBucket: getBucket,
- deleteBucket: deleteBucket,
- putBucketAcl: putBucketAcl, // BucketACL
- getBucketAcl: getBucketAcl,
- putBucketCors: putBucketCors, // BucketCors
- getBucketCors: getBucketCors,
- deleteBucketCors: deleteBucketCors,
- getBucketLocation: getBucketLocation, // BucketLocation
- getBucketPolicy: getBucketPolicy, // BucketPolicy
- putBucketPolicy: putBucketPolicy,
- deleteBucketPolicy: deleteBucketPolicy,
- putBucketTagging: putBucketTagging, // BucketTagging
- getBucketTagging: getBucketTagging,
- deleteBucketTagging: deleteBucketTagging,
- putBucketLifecycle: putBucketLifecycle, // BucketLifecycle
- getBucketLifecycle: getBucketLifecycle,
- deleteBucketLifecycle: deleteBucketLifecycle,
- putBucketVersioning: putBucketVersioning, // BucketVersioning
- getBucketVersioning: getBucketVersioning,
- putBucketReplication: putBucketReplication, // BucketReplication
- getBucketReplication: getBucketReplication,
- deleteBucketReplication: deleteBucketReplication,
- putBucketWebsite: putBucketWebsite, // BucketWebsite
- getBucketWebsite: getBucketWebsite,
- deleteBucketWebsite: deleteBucketWebsite,
- putBucketReferer: putBucketReferer, // BucketReferer
- getBucketReferer: getBucketReferer,
- putBucketDomain: putBucketDomain, // BucketDomain
- getBucketDomain: getBucketDomain,
- deleteBucketDomain: deleteBucketDomain,
- putBucketOrigin: putBucketOrigin, // BucketOrigin
- getBucketOrigin: getBucketOrigin,
- deleteBucketOrigin: deleteBucketOrigin,
- putBucketLogging: putBucketLogging, // BucketLogging
- getBucketLogging: getBucketLogging,
- putBucketInventory: putBucketInventory, // BucketInventory
- getBucketInventory: getBucketInventory,
- listBucketInventory: listBucketInventory,
- deleteBucketInventory: deleteBucketInventory,
- putBucketAccelerate: putBucketAccelerate,
- getBucketAccelerate: getBucketAccelerate,
- putBucketEncryption: putBucketEncryption,
- getBucketEncryption: getBucketEncryption,
- deleteBucketEncryption: deleteBucketEncryption,
- // Object 相关方法
- getObject: getObject,
- headObject: headObject,
- listObjectVersions: listObjectVersions,
- putObject: putObject,
- deleteObject: deleteObject,
- getObjectAcl: getObjectAcl,
- putObjectAcl: putObjectAcl,
- optionsObject: optionsObject,
- putObjectCopy: putObjectCopy,
- deleteMultipleObject: deleteMultipleObject,
- restoreObject: restoreObject,
- putObjectTagging: putObjectTagging,
- getObjectTagging: getObjectTagging,
- deleteObjectTagging: deleteObjectTagging,
- selectObjectContent: selectObjectContent,
- appendObject: appendObject,
- // 分块上传相关方法
- uploadPartCopy: uploadPartCopy,
- multipartInit: multipartInit,
- multipartUpload: multipartUpload,
- multipartComplete: multipartComplete,
- multipartList: multipartList,
- multipartListPart: multipartListPart,
- multipartAbort: multipartAbort,
- // 工具方法
- request: request,
- getObjectUrl: getObjectUrl,
- getAuth: getAuth
- };
- function warnOldApi(apiName, fn, proto) {
- util.each(['Cors', 'Acl'], function (suffix) {
- if (apiName.slice(-suffix.length) === suffix) {
- var oldName = apiName.slice(0, -suffix.length) + suffix.toUpperCase();
- var apiFn = util.apiWrapper(apiName, fn);
- var warned = false;
- proto[oldName] = function () {
- !warned && console.warn('warning: cos.' + oldName + ' has been deprecated. Please Use cos.' + apiName + ' instead.');
- warned = true;
- apiFn.apply(this, arguments);
- };
- }
- });
- }
- module.exports.init = function (COS, task) {
- task.transferToTaskMethod(API_MAP, 'putObject');
- util.each(API_MAP, function (fn, apiName) {
- COS.prototype[apiName] = util.apiWrapper(apiName, fn);
- warnOldApi(apiName, fn, COS.prototype);
- });
- };
- /***/ }),
- /* 20 */
- /***/ (function(module, exports) {
- var stringifyPrimitive = function (v) {
- switch (typeof v) {
- case 'string':
- return v;
- case 'boolean':
- return v ? 'true' : 'false';
- case 'number':
- return isFinite(v) ? v : '';
- default:
- return '';
- }
- };
- var queryStringify = function (obj, sep, eq, name) {
- sep = sep || '&';
- eq = eq || '=';
- if (obj === null) {
- obj = undefined;
- }
- if (typeof obj === 'object') {
- return Object.keys(obj).map(function (k) {
- var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
- if (Array.isArray(obj[k])) {
- return obj[k].map(function (v) {
- return ks + encodeURIComponent(stringifyPrimitive(v));
- }).join(sep);
- } else {
- return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
- }
- }).filter(Boolean).join(sep);
- }
- if (!name) return '';
- return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj));
- };
- var xhrRes = function (err, xhr, body) {
- var headers = {};
- xhr.getAllResponseHeaders().trim().split('\n').forEach(function (item) {
- if (item) {
- var index = item.indexOf(':');
- var key = item.substr(0, index).trim().toLowerCase();
- var val = item.substr(index + 1).trim();
- headers[key] = val;
- }
- });
- return {
- error: err,
- statusCode: xhr.status,
- statusMessage: xhr.statusText,
- headers: headers,
- body: body
- };
- };
- var xhrBody = function (xhr, dataType) {
- return !dataType && dataType === 'text' ? xhr.responseText : xhr.response;
- };
- var request = function (opt, callback) {
- // method
- var method = (opt.method || 'GET').toUpperCase();
- // url、qs
- var url = opt.url;
- if (opt.qs) {
- var qsStr = queryStringify(opt.qs);
- if (qsStr) {
- url += (url.indexOf('?') === -1 ? '?' : '&') + qsStr;
- }
- }
- // 创建 ajax 实例
- var xhr = new XMLHttpRequest();
- xhr.open(method, url, true);
- xhr.responseType = opt.dataType || 'text';
- // 处理 xhrFields 属性
- if (opt.xhrFields) {
- for (var xhrField in opt.xhrFields) {
- xhr[xhrField] = opt.xhrFields[xhrField];
- }
- }
- // 处理 headers
- var headers = opt.headers;
- if (headers) {
- for (var key in headers) {
- if (headers.hasOwnProperty(key) && key.toLowerCase() !== 'content-length' && key.toLowerCase() !== 'user-agent' && key.toLowerCase() !== 'origin' && key.toLowerCase() !== 'host') {
- xhr.setRequestHeader(key, headers[key]);
- }
- }
- }
- // onprogress
- if (opt.onProgress && xhr.upload) xhr.upload.onprogress = opt.onProgress;
- if (opt.onDownloadProgress) xhr.onprogress = opt.onDownloadProgress;
- // timeout
- if (opt.timeout) xhr.timeout = opt.timeout;
- xhr.ontimeout = function (event) {
- var error = new Error('timeout');
- callback(xhrRes(error, xhr));
- };
- // success 2xx/3xx/4xx
- xhr.onload = function () {
- callback(xhrRes(null, xhr, xhrBody(xhr, opt.dataType)));
- };
- // error 5xx/0 (网络错误、跨域报错、Https connect-src 限制的报错时 statusCode 为 0)
- xhr.onerror = function (err) {
- var body = xhrBody(xhr, opt.dataType);
- if (body) {
- // 5xx
- callback(xhrRes(null, xhr, body));
- } else {
- // 0
- var error = xhr.statusText;
- if (!error && xhr.status === 0) error = new Error('CORS blocked or network error');
- callback(xhrRes(error, xhr, body));
- }
- };
- // send
- xhr.send(opt.body || '');
- // 返回 ajax 实例,用于外部调用 xhr.abort
- return xhr;
- };
- module.exports = request;
- /***/ }),
- /* 21 */
- /***/ (function(module, exports, __webpack_require__) {
- var session = __webpack_require__(5);
- var Async = __webpack_require__(22);
- var EventProxy = __webpack_require__(4).EventProxy;
- var util = __webpack_require__(0);
- // 文件分块上传全过程,暴露的分块上传接口
- function sliceUploadFile(params, callback) {
- var self = this;
- var ep = new EventProxy();
- var TaskId = params.TaskId;
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var Body = params.Body;
- var ChunkSize = params.ChunkSize || params.SliceSize || self.options.ChunkSize;
- var AsyncLimit = params.AsyncLimit;
- var StorageClass = params.StorageClass;
- var ServerSideEncryption = params.ServerSideEncryption;
- var FileSize;
- var onProgress;
- var onHashProgress = params.onHashProgress;
- // 上传过程中出现错误,返回错误
- ep.on('error', function (err) {
- if (!self._isRunningTask(TaskId)) return;
- err.UploadId = params.UploadData.UploadId || '';
- return callback(err);
- });
- // 上传分块完成,开始 uploadSliceComplete 操作
- ep.on('upload_complete', function (UploadCompleteData) {
- var _UploadCompleteData = util.extend({
- UploadId: params.UploadData.UploadId || ''
- }, UploadCompleteData);
- callback(null, _UploadCompleteData);
- });
- // 上传分块完成,开始 uploadSliceComplete 操作
- ep.on('upload_slice_complete', function (UploadData) {
- var metaHeaders = {};
- util.each(params.Headers, function (val, k) {
- var shortKey = k.toLowerCase();
- if (shortKey.indexOf('x-cos-meta-') === 0 || shortKey === 'pic-operations') metaHeaders[k] = val;
- });
- uploadSliceComplete.call(self, {
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- UploadId: UploadData.UploadId,
- SliceList: UploadData.SliceList,
- Headers: metaHeaders
- }, function (err, data) {
- if (!self._isRunningTask(TaskId)) return;
- session.removeUsing(UploadData.UploadId);
- if (err) {
- onProgress(null, true);
- return ep.emit('error', err);
- }
- session.removeUploadId.call(self, UploadData.UploadId);
- onProgress({ loaded: FileSize, total: FileSize }, true);
- ep.emit('upload_complete', data);
- });
- });
- // 获取 UploadId 完成,开始上传每个分片
- ep.on('get_upload_data_finish', function (UploadData) {
- // 处理 UploadId 缓存
- var uuid = session.getFileId(Body, params.ChunkSize, Bucket, Key);
- uuid && session.saveUploadId.call(self, uuid, UploadData.UploadId, self.options.UploadIdCacheLimit); // 缓存 UploadId
- session.setUsing(UploadData.UploadId); // 标记 UploadId 为正在使用
- // 获取 UploadId
- onProgress(null, true); // 任务状态开始 uploading
- uploadSliceList.call(self, {
- TaskId: TaskId,
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- Body: Body,
- FileSize: FileSize,
- SliceSize: ChunkSize,
- AsyncLimit: AsyncLimit,
- ServerSideEncryption: ServerSideEncryption,
- UploadData: UploadData,
- Headers: params.Headers,
- onProgress: onProgress
- }, function (err, data) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) {
- onProgress(null, true);
- return ep.emit('error', err);
- }
- ep.emit('upload_slice_complete', data);
- });
- });
- // 开始获取文件 UploadId,里面会视情况计算 ETag,并比对,保证文件一致性,也优化上传
- ep.on('get_file_size_finish', function () {
- onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
- if (params.UploadData.UploadId) {
- ep.emit('get_upload_data_finish', params.UploadData);
- } else {
- var _params = util.extend({
- TaskId: TaskId,
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- Headers: params.Headers,
- StorageClass: StorageClass,
- Body: Body,
- FileSize: FileSize,
- SliceSize: ChunkSize,
- onHashProgress: onHashProgress
- }, params);
- getUploadIdAndPartList.call(self, _params, function (err, UploadData) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) return ep.emit('error', err);
- params.UploadData.UploadId = UploadData.UploadId;
- params.UploadData.PartList = UploadData.PartList;
- ep.emit('get_upload_data_finish', params.UploadData);
- });
- }
- });
- // 获取上传文件大小
- FileSize = params.ContentLength;
- delete params.ContentLength;
- !params.Headers && (params.Headers = {});
- util.each(params.Headers, function (item, key) {
- if (key.toLowerCase() === 'content-length') {
- delete params.Headers[key];
- }
- });
- // 控制分片大小
- (function () {
- var SIZE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024 * 2, 1024 * 4, 1024 * 5];
- var AutoChunkSize = 1024 * 1024;
- for (var i = 0; i < SIZE.length; i++) {
- AutoChunkSize = SIZE[i] * 1024 * 1024;
- if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
- }
- params.ChunkSize = params.SliceSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
- })();
- // 开始上传
- if (FileSize === 0) {
- params.Body = '';
- params.ContentLength = 0;
- params.SkipTask = true;
- self.putObject(params, callback);
- } else {
- ep.emit('get_file_size_finish');
- }
- }
- // 获取上传任务的 UploadId
- function getUploadIdAndPartList(params, callback) {
- var TaskId = params.TaskId;
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var StorageClass = params.StorageClass;
- var self = this;
- // 计算 ETag
- var ETagMap = {};
- var FileSize = params.FileSize;
- var SliceSize = params.SliceSize;
- var SliceCount = Math.ceil(FileSize / SliceSize);
- var FinishSliceCount = 0;
- var FinishSize = 0;
- var onHashProgress = util.throttleOnProgress.call(self, FileSize, params.onHashProgress);
- var getChunkETag = function (PartNumber, callback) {
- var start = SliceSize * (PartNumber - 1);
- var end = Math.min(start + SliceSize, FileSize);
- var ChunkSize = end - start;
- if (ETagMap[PartNumber]) {
- callback(null, {
- PartNumber: PartNumber,
- ETag: ETagMap[PartNumber],
- Size: ChunkSize
- });
- } else {
- util.fileSlice(params.Body, start, end, false, function (chunkItem) {
- util.getFileMd5(chunkItem, function (err, md5) {
- if (err) return callback(util.error(err));
- var ETag = '"' + md5 + '"';
- ETagMap[PartNumber] = ETag;
- FinishSliceCount += 1;
- FinishSize += ChunkSize;
- onHashProgress({ loaded: FinishSize, total: FileSize });
- callback(null, {
- PartNumber: PartNumber,
- ETag: ETag,
- Size: ChunkSize
- });
- });
- });
- }
- };
- // 通过和文件的 md5 对比,判断 UploadId 是否可用
- var isAvailableUploadList = function (PartList, callback) {
- var PartCount = PartList.length;
- // 如果没有分片,通过
- if (PartCount === 0) {
- return callback(null, true);
- }
- // 检查分片数量
- if (PartCount > SliceCount) {
- return callback(null, false);
- }
- // 检查分片大小
- if (PartCount > 1) {
- var PartSliceSize = Math.max(PartList[0].Size, PartList[1].Size);
- if (PartSliceSize !== SliceSize) {
- return callback(null, false);
- }
- }
- // 逐个分片计算并检查 ETag 是否一致
- var next = function (index) {
- if (index < PartCount) {
- var Part = PartList[index];
- getChunkETag(Part.PartNumber, function (err, chunk) {
- if (chunk && chunk.ETag === Part.ETag && chunk.Size === Part.Size) {
- next(index + 1);
- } else {
- callback(null, false);
- }
- });
- } else {
- callback(null, true);
- }
- };
- next(0);
- };
- var ep = new EventProxy();
- ep.on('error', function (errData) {
- if (!self._isRunningTask(TaskId)) return;
- return callback(errData);
- });
- // 存在 UploadId
- ep.on('upload_id_available', function (UploadData) {
- // 转换成 map
- var map = {};
- var list = [];
- util.each(UploadData.PartList, function (item) {
- map[item.PartNumber] = item;
- });
- for (var PartNumber = 1; PartNumber <= SliceCount; PartNumber++) {
- var item = map[PartNumber];
- if (item) {
- item.PartNumber = PartNumber;
- item.Uploaded = true;
- } else {
- item = {
- PartNumber: PartNumber,
- ETag: null,
- Uploaded: false
- };
- }
- list.push(item);
- }
- UploadData.PartList = list;
- callback(null, UploadData);
- });
- // 不存在 UploadId, 初始化生成 UploadId
- ep.on('no_available_upload_id', function () {
- if (!self._isRunningTask(TaskId)) return;
- var _params = util.extend({
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- Query: util.clone(params.Query),
- StorageClass: StorageClass,
- Body: params.Body
- }, params);
- var headers = util.clone(params.Headers);
- delete headers['x-cos-mime-limit'];
- _params.Headers = headers;
- self.multipartInit(_params, function (err, data) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) return ep.emit('error', err);
- var UploadId = data.UploadId;
- if (!UploadId) {
- return callback(util.error(new Error('no such upload id')));
- }
- ep.emit('upload_id_available', { UploadId: UploadId, PartList: [] });
- });
- });
- // 如果已存在 UploadId,找一个可以用的 UploadId
- ep.on('has_and_check_upload_id', function (UploadIdList) {
- // 串行地,找一个内容一致的 UploadId
- UploadIdList = UploadIdList.reverse();
- Async.eachLimit(UploadIdList, 1, function (UploadId, asyncCallback) {
- if (!self._isRunningTask(TaskId)) return;
- // 如果正在上传,跳过
- if (session.using[UploadId]) {
- asyncCallback(); // 检查下一个 UploadId
- return;
- }
- // 判断 UploadId 是否可用
- wholeMultipartListPart.call(self, {
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- UploadId: UploadId
- }, function (err, PartListData) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) {
- session.removeUsing(UploadId);
- return ep.emit('error', err);
- }
- var PartList = PartListData.PartList;
- PartList.forEach(function (item) {
- item.PartNumber *= 1;
- item.Size *= 1;
- item.ETag = item.ETag || '';
- });
- isAvailableUploadList(PartList, function (err, isAvailable) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) return ep.emit('error', err);
- if (isAvailable) {
- asyncCallback({
- UploadId: UploadId,
- PartList: PartList
- }); // 马上结束
- } else {
- asyncCallback(); // 检查下一个 UploadId
- }
- });
- });
- }, function (AvailableUploadData) {
- if (!self._isRunningTask(TaskId)) return;
- onHashProgress(null, true);
- if (AvailableUploadData && AvailableUploadData.UploadId) {
- ep.emit('upload_id_available', AvailableUploadData);
- } else {
- ep.emit('no_available_upload_id');
- }
- });
- });
- // 在本地缓存找可用的 UploadId
- ep.on('seek_local_avail_upload_id', function (RemoteUploadIdList) {
- // 在本地找可用的 UploadId
- var uuid = session.getFileId(params.Body, params.ChunkSize, Bucket, Key);
- var LocalUploadIdList = session.getUploadIdList.call(self, uuid);
- if (!uuid || !LocalUploadIdList) {
- ep.emit('has_and_check_upload_id', RemoteUploadIdList);
- return;
- }
- var next = function (index) {
- // 如果本地找不到可用 UploadId,再一个个遍历校验远端
- if (index >= LocalUploadIdList.length) {
- ep.emit('has_and_check_upload_id', RemoteUploadIdList);
- return;
- }
- var UploadId = LocalUploadIdList[index];
- // 如果不在远端 UploadId 列表里,跳过并删除
- if (!util.isInArray(RemoteUploadIdList, UploadId)) {
- session.removeUploadId.call(self, UploadId);
- next(index + 1);
- return;
- }
- // 如果正在上传,跳过
- if (session.using[UploadId]) {
- next(index + 1);
- return;
- }
- // 判断 UploadId 是否存在线上
- wholeMultipartListPart.call(self, {
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- UploadId: UploadId
- }, function (err, PartListData) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) {
- // 如果 UploadId 获取会出错,跳过并删除
- session.removeUploadId.call(self, UploadId);
- next(index + 1);
- } else {
- // 找到可用 UploadId
- ep.emit('upload_id_available', {
- UploadId: UploadId,
- PartList: PartListData.PartList
- });
- }
- });
- };
- next(0);
- });
- // 获取线上 UploadId 列表
- ep.on('get_remote_upload_id_list', function () {
- // 获取符合条件的 UploadId 列表,因为同一个文件可以有多个上传任务。
- wholeMultipartList.call(self, {
- Bucket: Bucket,
- Region: Region,
- Key: Key
- }, function (err, data) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) return ep.emit('error', err);
- // 整理远端 UploadId 列表
- var RemoteUploadIdList = util.filter(data.UploadList, function (item) {
- return item.Key === Key && (!StorageClass || item.StorageClass.toUpperCase() === StorageClass.toUpperCase());
- }).reverse().map(function (item) {
- return item.UploadId || item.UploadID;
- });
- if (RemoteUploadIdList.length) {
- ep.emit('seek_local_avail_upload_id', RemoteUploadIdList);
- } else {
- // 远端没有 UploadId,清理缓存的 UploadId
- var uuid = session.getFileId(params.Body, params.ChunkSize, Bucket, Key),
- LocalUploadIdList;
- if (uuid && (LocalUploadIdList = session.getUploadIdList.call(self, uuid))) {
- util.each(LocalUploadIdList, function (UploadId) {
- session.removeUploadId.call(self, UploadId);
- });
- }
- ep.emit('no_available_upload_id');
- }
- });
- });
- // 开始找可用 UploadId
- ep.emit('get_remote_upload_id_list');
- }
- // 获取符合条件的全部上传任务 (条件包括 Bucket, Region, Prefix)
- function wholeMultipartList(params, callback) {
- var self = this;
- var UploadList = [];
- var sendParams = {
- Bucket: params.Bucket,
- Region: params.Region,
- Prefix: params.Key
- };
- var next = function () {
- self.multipartList(sendParams, function (err, data) {
- if (err) return callback(err);
- UploadList.push.apply(UploadList, data.Upload || []);
- if (data.IsTruncated === 'true') {
- // 列表不完整
- sendParams.KeyMarker = data.NextKeyMarker;
- sendParams.UploadIdMarker = data.NextUploadIdMarker;
- next();
- } else {
- callback(null, { UploadList: UploadList });
- }
- });
- };
- next();
- }
- // 获取指定上传任务的分块列表
- function wholeMultipartListPart(params, callback) {
- var self = this;
- var PartList = [];
- var sendParams = {
- Bucket: params.Bucket,
- Region: params.Region,
- Key: params.Key,
- UploadId: params.UploadId
- };
- var next = function () {
- self.multipartListPart(sendParams, function (err, data) {
- if (err) return callback(err);
- PartList.push.apply(PartList, data.Part || []);
- if (data.IsTruncated === 'true') {
- // 列表不完整
- sendParams.PartNumberMarker = data.NextPartNumberMarker;
- next();
- } else {
- callback(null, { PartList: PartList });
- }
- });
- };
- next();
- }
- // 上传文件分块,包括
- /*
- UploadId (上传任务编号)
- AsyncLimit (并发量),
- SliceList (上传的分块数组),
- FilePath (本地文件的位置),
- SliceSize (文件分块大小)
- FileSize (文件大小)
- onProgress (上传成功之后的回调函数)
- */
- function uploadSliceList(params, cb) {
- var self = this;
- var TaskId = params.TaskId;
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var UploadData = params.UploadData;
- var FileSize = params.FileSize;
- var SliceSize = params.SliceSize;
- var ChunkParallel = Math.min(params.AsyncLimit || self.options.ChunkParallelLimit || 1, 256);
- var Body = params.Body;
- var SliceCount = Math.ceil(FileSize / SliceSize);
- var FinishSize = 0;
- var ServerSideEncryption = params.ServerSideEncryption;
- var Headers = params.Headers;
- var needUploadSlices = util.filter(UploadData.PartList, function (SliceItem) {
- if (SliceItem['Uploaded']) {
- FinishSize += SliceItem['PartNumber'] >= SliceCount ? FileSize % SliceSize || SliceSize : SliceSize;
- }
- return !SliceItem['Uploaded'];
- });
- var onProgress = params.onProgress;
- Async.eachLimit(needUploadSlices, ChunkParallel, function (SliceItem, asyncCallback) {
- if (!self._isRunningTask(TaskId)) return;
- var PartNumber = SliceItem['PartNumber'];
- var currentSize = Math.min(FileSize, SliceItem['PartNumber'] * SliceSize) - (SliceItem['PartNumber'] - 1) * SliceSize;
- var preAddSize = 0;
- uploadSliceItem.call(self, {
- TaskId: TaskId,
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- SliceSize: SliceSize,
- FileSize: FileSize,
- PartNumber: PartNumber,
- ServerSideEncryption: ServerSideEncryption,
- Body: Body,
- UploadData: UploadData,
- Headers: Headers,
- onProgress: function (data) {
- FinishSize += data.loaded - preAddSize;
- preAddSize = data.loaded;
- onProgress({ loaded: FinishSize, total: FileSize });
- }
- }, function (err, data) {
- if (!self._isRunningTask(TaskId)) return;
- 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 )';
- if (err) {
- FinishSize -= preAddSize;
- } else {
- FinishSize += currentSize - preAddSize;
- SliceItem.ETag = data.ETag;
- }
- onProgress({ loaded: FinishSize, total: FileSize });
- asyncCallback(err || null, data);
- });
- }, function (err) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) return cb(err);
- cb(null, {
- UploadId: UploadData.UploadId,
- SliceList: UploadData.PartList
- });
- });
- }
- // 上传指定分片
- function uploadSliceItem(params, callback) {
- var self = this;
- var TaskId = params.TaskId;
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var FileSize = params.FileSize;
- var FileBody = params.Body;
- var PartNumber = params.PartNumber * 1;
- var SliceSize = params.SliceSize;
- var ServerSideEncryption = params.ServerSideEncryption;
- var UploadData = params.UploadData;
- var Headers = params.Headers || {};
- var ChunkRetryTimes = self.options.ChunkRetryTimes + 1;
- var start = SliceSize * (PartNumber - 1);
- var ContentLength = SliceSize;
- var end = start + SliceSize;
- if (end > FileSize) {
- end = FileSize;
- ContentLength = end - start;
- }
- var headersWhiteList = ['x-cos-traffic-limit', 'x-cos-mime-limit'];
- var headers = {};
- util.each(Headers, function (v, k) {
- if (headersWhiteList.indexOf(k) > -1) {
- headers[k] = v;
- }
- });
- var PartItem = UploadData.PartList[PartNumber - 1];
- Async.retry(ChunkRetryTimes, function (tryCallback) {
- if (!self._isRunningTask(TaskId)) return;
- util.fileSlice(FileBody, start, end, true, function (Body) {
- self.multipartUpload({
- TaskId: TaskId,
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- ContentLength: ContentLength,
- PartNumber: PartNumber,
- UploadId: UploadData.UploadId,
- ServerSideEncryption: ServerSideEncryption,
- Body: Body,
- Headers: headers,
- onProgress: params.onProgress
- }, function (err, data) {
- if (!self._isRunningTask(TaskId)) return;
- if (err) return tryCallback(err);
- PartItem.Uploaded = true;
- return tryCallback(null, data);
- });
- });
- }, function (err, data) {
- if (!self._isRunningTask(TaskId)) return;
- return callback(err, data);
- });
- }
- // 完成分块上传
- function uploadSliceComplete(params, callback) {
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var UploadId = params.UploadId;
- var SliceList = params.SliceList;
- var self = this;
- var ChunkRetryTimes = this.options.ChunkRetryTimes + 1;
- var Headers = params.Headers;
- var Parts = SliceList.map(function (item) {
- return {
- PartNumber: item.PartNumber,
- ETag: item.ETag
- };
- });
- // 完成上传的请求也做重试
- Async.retry(ChunkRetryTimes, function (tryCallback) {
- self.multipartComplete({
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- UploadId: UploadId,
- Parts: Parts,
- Headers: Headers
- }, tryCallback);
- }, function (err, data) {
- callback(err, data);
- });
- }
- // 抛弃分块上传任务
- /*
- AsyncLimit (抛弃上传任务的并发量),
- UploadId (上传任务的编号,当 Level 为 task 时候需要)
- Level (抛弃分块上传任务的级别,task : 抛弃指定的上传任务,file : 抛弃指定的文件对应的上传任务,其他值 :抛弃指定Bucket 的全部上传任务)
- */
- function abortUploadTask(params, callback) {
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var UploadId = params.UploadId;
- var Level = params.Level || 'task';
- var AsyncLimit = params.AsyncLimit;
- var self = this;
- var ep = new EventProxy();
- ep.on('error', function (errData) {
- return callback(errData);
- });
- // 已经获取到需要抛弃的任务列表
- ep.on('get_abort_array', function (AbortArray) {
- abortUploadTaskArray.call(self, {
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- Headers: params.Headers,
- AsyncLimit: AsyncLimit,
- AbortArray: AbortArray
- }, callback);
- });
- if (Level === 'bucket') {
- // Bucket 级别的任务抛弃,抛弃该 Bucket 下的全部上传任务
- wholeMultipartList.call(self, {
- Bucket: Bucket,
- Region: Region
- }, function (err, data) {
- if (err) return callback(err);
- ep.emit('get_abort_array', data.UploadList || []);
- });
- } else if (Level === 'file') {
- // 文件级别的任务抛弃,抛弃该文件的全部上传任务
- if (!Key) return callback(util.error(new Error('abort_upload_task_no_key')));
- wholeMultipartList.call(self, {
- Bucket: Bucket,
- Region: Region,
- Key: Key
- }, function (err, data) {
- if (err) return callback(err);
- ep.emit('get_abort_array', data.UploadList || []);
- });
- } else if (Level === 'task') {
- // 单个任务级别的任务抛弃,抛弃指定 UploadId 的上传任务
- if (!UploadId) return callback(util.error(new Error('abort_upload_task_no_id')));
- if (!Key) return callback(util.error(new Error('abort_upload_task_no_key')));
- ep.emit('get_abort_array', [{
- Key: Key,
- UploadId: UploadId
- }]);
- } else {
- return callback(util.error(new Error('abort_unknown_level')));
- }
- }
- // 批量抛弃分块上传任务
- function abortUploadTaskArray(params, callback) {
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var AbortArray = params.AbortArray;
- var AsyncLimit = params.AsyncLimit || 1;
- var self = this;
- var index = 0;
- var resultList = new Array(AbortArray.length);
- Async.eachLimit(AbortArray, AsyncLimit, function (AbortItem, nextItem) {
- var eachIndex = index;
- if (Key && Key !== AbortItem.Key) {
- resultList[eachIndex] = { error: { KeyNotMatch: true } };
- nextItem(null);
- return;
- }
- var UploadId = AbortItem.UploadId || AbortItem.UploadID;
- self.multipartAbort({
- Bucket: Bucket,
- Region: Region,
- Key: AbortItem.Key,
- Headers: params.Headers,
- UploadId: UploadId
- }, function (err) {
- var task = {
- Bucket: Bucket,
- Region: Region,
- Key: AbortItem.Key,
- UploadId: UploadId
- };
- resultList[eachIndex] = { error: err, task: task };
- nextItem(null);
- });
- index++;
- }, function (err) {
- if (err) return callback(err);
- var successList = [];
- var errorList = [];
- for (var i = 0, len = resultList.length; i < len; i++) {
- var item = resultList[i];
- if (item['task']) {
- if (item['error']) {
- errorList.push(item['task']);
- } else {
- successList.push(item['task']);
- }
- }
- }
- return callback(null, {
- successList: successList,
- errorList: errorList
- });
- });
- }
- // 高级上传
- function uploadFile(params, callback) {
- var self = this;
- // 判断多大的文件使用分片上传
- var SliceSize = params.SliceSize === undefined ? self.options.SliceSize : params.SliceSize;
- var taskList = [];
- var Body = params.Body;
- var FileSize = Body.size || Body.length || 0;
- var fileInfo = { TaskId: '' };
- // 整理 option,用于返回给回调
- util.each(params, function (v, k) {
- if (typeof v !== 'object' && typeof v !== 'function') {
- fileInfo[k] = v;
- }
- });
- // 处理文件 TaskReady
- var _onTaskReady = params.onTaskReady;
- var onTaskReady = function (tid) {
- fileInfo.TaskId = tid;
- _onTaskReady && _onTaskReady(tid);
- };
- params.onTaskReady = onTaskReady;
- // 处理文件完成
- var _onFileFinish = params.onFileFinish;
- var onFileFinish = function (err, data) {
- _onFileFinish && _onFileFinish(err, data, fileInfo);
- callback && callback(err, data);
- };
- // 添加上传任务,超过阈值使用分块上传,小于等于则简单上传
- var api = FileSize > SliceSize ? 'sliceUploadFile' : 'putObject';
- taskList.push({
- api: api,
- params: params,
- callback: onFileFinish
- });
- self._addTasks(taskList);
- }
- // 批量上传文件
- function uploadFiles(params, callback) {
- var self = this;
- // 判断多大的文件使用分片上传
- var SliceSize = params.SliceSize === undefined ? self.options.SliceSize : params.SliceSize;
- // 汇总返回进度
- var TotalSize = 0;
- var TotalFinish = 0;
- var onTotalProgress = util.throttleOnProgress.call(self, TotalFinish, params.onProgress);
- // 汇总返回回调
- var unFinishCount = params.files.length;
- var _onTotalFileFinish = params.onFileFinish;
- var resultList = Array(unFinishCount);
- var onTotalFileFinish = function (err, data, options) {
- onTotalProgress(null, true);
- _onTotalFileFinish && _onTotalFileFinish(err, data, options);
- resultList[options.Index] = {
- options: options,
- error: err,
- data: data
- };
- if (--unFinishCount <= 0 && callback) {
- callback(null, { files: resultList });
- }
- };
- // 开始处理每个文件
- var taskList = [];
- util.each(params.files, function (fileParams, index) {
- (function () {
- // 对齐 nodejs 缩进
- var Body = fileParams.Body;
- var FileSize = Body.size || Body.length || 0;
- var fileInfo = { Index: index, TaskId: '' };
- // 更新文件总大小
- TotalSize += FileSize;
- // 整理 option,用于返回给回调
- util.each(fileParams, function (v, k) {
- if (typeof v !== 'object' && typeof v !== 'function') {
- fileInfo[k] = v;
- }
- });
- // 处理单个文件 TaskReady
- var _onTaskReady = fileParams.onTaskReady;
- var onTaskReady = function (tid) {
- fileInfo.TaskId = tid;
- _onTaskReady && _onTaskReady(tid);
- };
- fileParams.onTaskReady = onTaskReady;
- // 处理单个文件进度
- var PreAddSize = 0;
- var _onProgress = fileParams.onProgress;
- var onProgress = function (info) {
- TotalFinish = TotalFinish - PreAddSize + info.loaded;
- PreAddSize = info.loaded;
- _onProgress && _onProgress(info);
- onTotalProgress({ loaded: TotalFinish, total: TotalSize });
- };
- fileParams.onProgress = onProgress;
- // 处理单个文件完成
- var _onFileFinish = fileParams.onFileFinish;
- var onFileFinish = function (err, data) {
- _onFileFinish && _onFileFinish(err, data);
- onTotalFileFinish && onTotalFileFinish(err, data, fileInfo);
- };
- // 添加上传任务
- var api = FileSize > SliceSize ? 'sliceUploadFile' : 'putObject';
- taskList.push({
- api: api,
- params: fileParams,
- callback: onFileFinish
- });
- })();
- });
- self._addTasks(taskList);
- }
- // 分片复制文件
- function sliceCopyFile(params, callback) {
- var ep = new EventProxy();
- var self = this;
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var CopySource = params.CopySource;
- var m = util.getSourceParams.call(this, CopySource);
- if (!m) {
- callback(util.error(new Error('CopySource format error')));
- return;
- }
- var SourceBucket = m.Bucket;
- var SourceRegion = m.Region;
- var SourceKey = decodeURIComponent(m.Key);
- var CopySliceSize = params.CopySliceSize === undefined ? self.options.CopySliceSize : params.CopySliceSize;
- CopySliceSize = Math.max(0, CopySliceSize);
- var ChunkSize = params.CopyChunkSize || this.options.CopyChunkSize;
- var ChunkParallel = this.options.CopyChunkParallelLimit;
- var FinishSize = 0;
- var FileSize;
- var onProgress;
- // 分片复制完成,开始 multipartComplete 操作
- ep.on('copy_slice_complete', function (UploadData) {
- var metaHeaders = {};
- util.each(params.Headers, function (val, k) {
- if (k.toLowerCase().indexOf('x-cos-meta-') === 0) metaHeaders[k] = val;
- });
- var Parts = util.map(UploadData.PartList, function (item) {
- return {
- PartNumber: item.PartNumber,
- ETag: item.ETag
- };
- });
- self.multipartComplete({
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- UploadId: UploadData.UploadId,
- Parts: Parts
- }, function (err, data) {
- if (err) {
- onProgress(null, true);
- return callback(err);
- }
- onProgress({ loaded: FileSize, total: FileSize }, true);
- callback(null, data);
- });
- });
- ep.on('get_copy_data_finish', function (UploadData) {
- Async.eachLimit(UploadData.PartList, ChunkParallel, function (SliceItem, asyncCallback) {
- var PartNumber = SliceItem.PartNumber;
- var CopySourceRange = SliceItem.CopySourceRange;
- var currentSize = SliceItem.end - SliceItem.start;
- copySliceItem.call(self, {
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- CopySource: CopySource,
- UploadId: UploadData.UploadId,
- PartNumber: PartNumber,
- CopySourceRange: CopySourceRange
- }, function (err, data) {
- if (err) return asyncCallback(err);
- FinishSize += currentSize;
- onProgress({ loaded: FinishSize, total: FileSize });
- SliceItem.ETag = data.ETag;
- asyncCallback(err || null, data);
- });
- }, function (err) {
- if (err) {
- onProgress(null, true);
- return callback(err);
- }
- ep.emit('copy_slice_complete', UploadData);
- });
- });
- ep.on('get_file_size_finish', function (SourceHeaders) {
- // 控制分片大小
- (function () {
- var SIZE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 1024 * 2, 1024 * 4, 1024 * 5];
- var AutoChunkSize = 1024 * 1024;
- for (var i = 0; i < SIZE.length; i++) {
- AutoChunkSize = SIZE[i] * 1024 * 1024;
- if (FileSize / AutoChunkSize <= self.options.MaxPartNumber) break;
- }
- params.ChunkSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
- var ChunkCount = Math.ceil(FileSize / ChunkSize);
- var list = [];
- for (var partNumber = 1; partNumber <= ChunkCount; partNumber++) {
- var start = (partNumber - 1) * ChunkSize;
- var end = partNumber * ChunkSize < FileSize ? partNumber * ChunkSize - 1 : FileSize - 1;
- var item = {
- PartNumber: partNumber,
- start: start,
- end: end,
- CopySourceRange: "bytes=" + start + "-" + end
- };
- list.push(item);
- }
- params.PartList = list;
- })();
- var TargetHeader;
- if (params.Headers['x-cos-metadata-directive'] === 'Replaced') {
- TargetHeader = params.Headers;
- } else {
- TargetHeader = SourceHeaders;
- }
- TargetHeader['x-cos-storage-class'] = params.Headers['x-cos-storage-class'] || SourceHeaders['x-cos-storage-class'];
- TargetHeader = util.clearKey(TargetHeader);
- /**
- * 对于归档存储的对象,如果未恢复副本,则不允许 Copy
- */
- if (SourceHeaders['x-cos-storage-class'] === 'ARCHIVE' || SourceHeaders['x-cos-storage-class'] === 'DEEP_ARCHIVE') {
- var restoreHeader = SourceHeaders['x-cos-restore'];
- if (!restoreHeader || restoreHeader === 'ongoing-request="true"') {
- callback(util.error(new Error('Unrestored archive object is not allowed to be copied')));
- return;
- }
- }
- /**
- * 去除一些无用的头部,规避 multipartInit 出错
- * 这些头部通常是在 putObjectCopy 时才使用
- */
- delete TargetHeader['x-cos-copy-source'];
- delete TargetHeader['x-cos-metadata-directive'];
- delete TargetHeader['x-cos-copy-source-If-Modified-Since'];
- delete TargetHeader['x-cos-copy-source-If-Unmodified-Since'];
- delete TargetHeader['x-cos-copy-source-If-Match'];
- delete TargetHeader['x-cos-copy-source-If-None-Match'];
- self.multipartInit({
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- Headers: TargetHeader
- }, function (err, data) {
- if (err) return callback(err);
- params.UploadId = data.UploadId;
- ep.emit('get_copy_data_finish', params);
- });
- });
- // 获取远端复制源文件的大小
- self.headObject({
- Bucket: SourceBucket,
- Region: SourceRegion,
- Key: SourceKey
- }, function (err, data) {
- if (err) {
- if (err.statusCode && err.statusCode === 404) {
- callback(util.error(err, { ErrorStatus: SourceKey + ' Not Exist' }));
- } else {
- callback(err);
- }
- return;
- }
- FileSize = params.FileSize = data.headers['content-length'];
- if (FileSize === undefined || !FileSize) {
- 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 )')));
- return;
- }
- onProgress = util.throttleOnProgress.call(self, FileSize, params.onProgress);
- // 开始上传
- if (FileSize <= CopySliceSize) {
- if (!params.Headers['x-cos-metadata-directive']) {
- params.Headers['x-cos-metadata-directive'] = 'Copy';
- }
- self.putObjectCopy(params, function (err, data) {
- if (err) {
- onProgress(null, true);
- return callback(err);
- }
- onProgress({ loaded: FileSize, total: FileSize }, true);
- callback(err, data);
- });
- } else {
- var resHeaders = data.headers;
- var SourceHeaders = {
- 'Cache-Control': resHeaders['cache-control'],
- 'Content-Disposition': resHeaders['content-disposition'],
- 'Content-Encoding': resHeaders['content-encoding'],
- 'Content-Type': resHeaders['content-type'],
- 'Expires': resHeaders['expires'],
- 'x-cos-storage-class': resHeaders['x-cos-storage-class']
- };
- util.each(resHeaders, function (v, k) {
- var metaPrefix = 'x-cos-meta-';
- if (k.indexOf(metaPrefix) === 0 && k.length > metaPrefix.length) {
- SourceHeaders[k] = v;
- }
- });
- ep.emit('get_file_size_finish', SourceHeaders);
- }
- });
- }
- // 复制指定分片
- function copySliceItem(params, callback) {
- var TaskId = params.TaskId;
- var Bucket = params.Bucket;
- var Region = params.Region;
- var Key = params.Key;
- var CopySource = params.CopySource;
- var UploadId = params.UploadId;
- var PartNumber = params.PartNumber * 1;
- var CopySourceRange = params.CopySourceRange;
- var ChunkRetryTimes = this.options.ChunkRetryTimes + 1;
- var self = this;
- Async.retry(ChunkRetryTimes, function (tryCallback) {
- self.uploadPartCopy({
- TaskId: TaskId,
- Bucket: Bucket,
- Region: Region,
- Key: Key,
- CopySource: CopySource,
- UploadId: UploadId,
- PartNumber: PartNumber,
- CopySourceRange: CopySourceRange
- }, function (err, data) {
- tryCallback(err || null, data);
- });
- }, function (err, data) {
- return callback(err, data);
- });
- }
- var API_MAP = {
- sliceUploadFile: sliceUploadFile,
- abortUploadTask: abortUploadTask,
- uploadFile: uploadFile,
- uploadFiles: uploadFiles,
- sliceCopyFile: sliceCopyFile
- };
- module.exports.init = function (COS, task) {
- task.transferToTaskMethod(API_MAP, 'sliceUploadFile');
- util.each(API_MAP, function (fn, apiName) {
- COS.prototype[apiName] = util.apiWrapper(apiName, fn);
- });
- };
- /***/ }),
- /* 22 */
- /***/ (function(module, exports) {
- var eachLimit = function (arr, limit, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length || limit <= 0) {
- return callback();
- }
- var completed = 0;
- var started = 0;
- var running = 0;
- (function replenish() {
- if (completed >= arr.length) {
- return callback();
- }
- while (running < limit && started < arr.length) {
- started += 1;
- running += 1;
- iterator(arr[started - 1], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- } else {
- completed += 1;
- running -= 1;
- if (completed >= arr.length) {
- callback();
- } else {
- replenish();
- }
- }
- });
- }
- })();
- };
- var retry = function (times, iterator, callback) {
- var next = function (index) {
- iterator(function (err, data) {
- if (err && index < times) {
- next(index + 1);
- } else {
- callback(err, data);
- }
- });
- };
- if (times < 1) {
- callback();
- } else {
- next(1);
- }
- };
- var async = {
- eachLimit: eachLimit,
- retry: retry
- };
- module.exports = async;
- /***/ })
- /******/ ]);
- });
|