[{"data":1,"prerenderedAt":634},["ShallowReactive",2],{"navigation":3,"-guide-http-server":137,"-guide-http-server-surround":629},[4,26],{"title":5,"path":6,"stem":7,"children":8,"icon":10},"Getting Started","\u002Fguide","1.guide\u002F1.index",[9,11,16,21],{"title":5,"path":6,"stem":7,"icon":10},"ph:book-open-duotone",{"title":12,"path":13,"stem":14,"icon":15},"Utilities","\u002Fguide\u002Futils","1.guide\u002F2.utils","et:tools-2",{"title":17,"path":18,"stem":19,"icon":20},"HTTP Server","\u002Fguide\u002Fhttp-server","1.guide\u002F3.http-server","ic:baseline-http",{"title":22,"path":23,"stem":24,"icon":25},"Custom Driver","\u002Fguide\u002Fcustom-driver","1.guide\u002F4.custom-driver","carbon:area-custom",{"title":27,"path":28,"stem":29,"children":30,"icon":32},"Drivers","\u002Fdrivers","2.drivers\u002F0.index",[31,33,38,43,48,53,58,63,68,73,77,82,87,92,97,102,107,112,117,122,127,132],{"title":27,"path":28,"stem":29,"icon":32},"icon-park-outline:hard-disk",{"title":34,"path":35,"stem":36,"icon":37},"Azure","\u002Fdrivers\u002Fazure","2.drivers\u002Fazure","mdi:microsoft-azure",{"title":39,"path":40,"stem":41,"icon":42},"Browser","\u002Fdrivers\u002Fbrowser","2.drivers\u002Fbrowser","ph:browser-thin",{"title":44,"path":45,"stem":46,"icon":47},"Capacitor Preferences","\u002Fdrivers\u002Fcapacitor-preferences","2.drivers\u002Fcapacitor-preferences","nonicons:capacitor-16",{"title":49,"path":50,"stem":51,"icon":52},"Cloudflare","\u002Fdrivers\u002Fcloudflare","2.drivers\u002Fcloudflare","devicon-plain:cloudflareworkers",{"title":54,"path":55,"stem":56,"icon":57},"SQL Database","\u002Fdrivers\u002Fdatabase","2.drivers\u002Fdatabase","ph:database",{"title":59,"path":60,"stem":61,"icon":62},"Deno KV","\u002Fdrivers\u002Fdeno","2.drivers\u002Fdeno","simple-icons:deno",{"title":64,"path":65,"stem":66,"icon":67},"Filesystem (Node.js)","\u002Fdrivers\u002Ffs","2.drivers\u002Ffs","ph:file-light",{"title":69,"path":70,"stem":71,"icon":72},"GitHub","\u002Fdrivers\u002Fgithub","2.drivers\u002Fgithub","mdi:github",{"title":74,"path":75,"stem":76,"icon":20},"HTTP","\u002Fdrivers\u002Fhttp","2.drivers\u002Fhttp",{"title":78,"path":79,"stem":80,"icon":81},"LRU Cache","\u002Fdrivers\u002Flru-cache","2.drivers\u002Flru-cache","material-symbols:cached-rounded",{"title":83,"path":84,"stem":85,"icon":86},"Memory","\u002Fdrivers\u002Fmemory","2.drivers\u002Fmemory","bi:memory",{"title":88,"path":89,"stem":90,"icon":91},"MongoDB","\u002Fdrivers\u002Fmongodb","2.drivers\u002Fmongodb","teenyicons:mongodb-outline",{"title":93,"path":94,"stem":95,"icon":96},"Netlify Blobs","\u002Fdrivers\u002Fnetlify","2.drivers\u002Fnetlify","teenyicons:netlify-solid",{"title":98,"path":99,"stem":100,"icon":101},"Null","\u002Fdrivers\u002Fnull","2.drivers\u002Fnull","bi:trash3-fill",{"title":103,"path":104,"stem":105,"icon":106},"Overlay","\u002Fdrivers\u002Foverlay","2.drivers\u002Foverlay","carbon:overlay",{"title":108,"path":109,"stem":110,"icon":111},"PlanetScale","\u002Fdrivers\u002Fplanetscale","2.drivers\u002Fplanetscale","simple-icons:planetscale",{"title":113,"path":114,"stem":115,"icon":116},"Redis","\u002Fdrivers\u002Fredis","2.drivers\u002Fredis","simple-icons:redis",{"title":118,"path":119,"stem":120,"icon":121},"S3","\u002Fdrivers\u002Fs3","2.drivers\u002Fs3","simple-icons:amazons3",{"title":123,"path":124,"stem":125,"icon":126},"UploadThing","\u002Fdrivers\u002Fuploadthing","2.drivers\u002Fuploadthing","qlementine-icons:cloud-16",{"title":128,"path":129,"stem":130,"icon":131},"Upstash","\u002Fdrivers\u002Fupstash","2.drivers\u002Fupstash","simple-icons:upstash",{"title":133,"path":134,"stem":135,"icon":136},"Vercel","\u002Fdrivers\u002Fvercel","2.drivers\u002Fvercel","gg:vercel",{"id":138,"title":17,"body":139,"description":623,"extension":624,"meta":625,"navigation":626,"path":18,"seo":627,"stem":19,"__hash__":628},"content\u002F1.guide\u002F3.http-server.md",{"type":140,"value":141,"toc":618,"icon":20},"minimark",[142,146,151,159,381,402,416,420,427,528,532,596,614],[143,144,145],"p",{},"Request url is mapped to a key and method\u002Fbody is mapped to a function. See below for supported HTTP methods.",[147,148,150],"h2",{"id":149},"storage-server","Storage Server",[143,152,153,154,158],{},"Programmatic usage of creating an HTTP server exposing methods to communicate with the ",[155,156,157],"code",{},"storage"," instance:",[160,161,167],"pre",{"className":162,"code":163,"filename":164,"language":165,"meta":166,"style":166},"language-js shiki shiki-themes github-light github-dark github-dark","import { listen } from \"listhen\";\nimport { createStorage } from \"unstorage\";\nimport { createStorageServer } from \"unstorage\u002Fserver\";\n\nconst storage = createStorage();\nconst storageServer = createStorageServer(storage, {\n  authorize(req) {\n    \u002F\u002F req: { key, type, event }\n    if (req.type === \"read\" && req.key.startsWith(\"private:\")) {\n      throw new Error(\"Unauthorized Read\");\n    }\n  },\n});\n\n\u002F\u002F Alternatively we can use `storageServer.handle` as a middleware\nawait listen(storageServer.handle);\n","server.js","js","",[155,168,169,192,207,222,229,249,265,281,288,320,340,346,352,358,363,369],{"__ignoreMap":166},[170,171,174,178,182,185,189],"span",{"class":172,"line":173},"line",1,[170,175,177],{"class":176},"so5gQ","import",[170,179,181],{"class":180},"slsVL"," { listen } ",[170,183,184],{"class":176},"from",[170,186,188],{"class":187},"sfrk1"," \"listhen\"",[170,190,191],{"class":180},";\n",[170,193,195,197,200,202,205],{"class":172,"line":194},2,[170,196,177],{"class":176},[170,198,199],{"class":180}," { createStorage } ",[170,201,184],{"class":176},[170,203,204],{"class":187}," \"unstorage\"",[170,206,191],{"class":180},[170,208,210,212,215,217,220],{"class":172,"line":209},3,[170,211,177],{"class":176},[170,213,214],{"class":180}," { createStorageServer } ",[170,216,184],{"class":176},[170,218,219],{"class":187}," \"unstorage\u002Fserver\"",[170,221,191],{"class":180},[170,223,225],{"class":172,"line":224},4,[170,226,228],{"emptyLinePlaceholder":227},true,"\n",[170,230,232,235,239,242,246],{"class":172,"line":231},5,[170,233,234],{"class":176},"const",[170,236,238],{"class":237},"suiK_"," storage",[170,240,241],{"class":176}," =",[170,243,245],{"class":244},"shcOC"," createStorage",[170,247,248],{"class":180},"();\n",[170,250,252,254,257,259,262],{"class":172,"line":251},6,[170,253,234],{"class":176},[170,255,256],{"class":237}," storageServer",[170,258,241],{"class":176},[170,260,261],{"class":244}," createStorageServer",[170,263,264],{"class":180},"(storage, {\n",[170,266,268,271,274,278],{"class":172,"line":267},7,[170,269,270],{"class":244},"  authorize",[170,272,273],{"class":180},"(",[170,275,277],{"class":276},"sQHwn","req",[170,279,280],{"class":180},") {\n",[170,282,284],{"class":172,"line":283},8,[170,285,287],{"class":286},"sCsY4","    \u002F\u002F req: { key, type, event }\n",[170,289,291,294,297,300,303,306,309,312,314,317],{"class":172,"line":290},9,[170,292,293],{"class":176},"    if",[170,295,296],{"class":180}," (req.type ",[170,298,299],{"class":176},"===",[170,301,302],{"class":187}," \"read\"",[170,304,305],{"class":176}," &&",[170,307,308],{"class":180}," req.key.",[170,310,311],{"class":244},"startsWith",[170,313,273],{"class":180},[170,315,316],{"class":187},"\"private:\"",[170,318,319],{"class":180},")) {\n",[170,321,323,326,329,332,334,337],{"class":172,"line":322},10,[170,324,325],{"class":176},"      throw",[170,327,328],{"class":176}," new",[170,330,331],{"class":244}," Error",[170,333,273],{"class":180},[170,335,336],{"class":187},"\"Unauthorized Read\"",[170,338,339],{"class":180},");\n",[170,341,343],{"class":172,"line":342},11,[170,344,345],{"class":180},"    }\n",[170,347,349],{"class":172,"line":348},12,[170,350,351],{"class":180},"  },\n",[170,353,355],{"class":172,"line":354},13,[170,356,357],{"class":180},"});\n",[170,359,361],{"class":172,"line":360},14,[170,362,228],{"emptyLinePlaceholder":227},[170,364,366],{"class":172,"line":365},15,[170,367,368],{"class":286},"\u002F\u002F Alternatively we can use `storageServer.handle` as a middleware\n",[170,370,372,375,378],{"class":172,"line":371},16,[170,373,374],{"class":176},"await",[170,376,377],{"class":244}," listen",[170,379,380],{"class":180},"(storageServer.handle);\n",[143,382,383,384,387,388,395,396,401],{},"The ",[155,385,386],{},"storageServer"," is an ",[389,390,394],"a",{"href":391,"rel":392},"https:\u002F\u002Fgithub.com\u002Funjs\u002Fh3",[393],"nofollow","h3"," instance. Check out also ",[389,397,400],{"href":398,"rel":399},"https:\u002F\u002Fgithub.com\u002Funjs\u002Flisthen",[393],"listhen"," for an elegant HTTP listener.",[403,404,405],"warning",{},[143,406,407,411,412,415],{},[408,409,410],"strong",{},"🛡️ Security Note:"," Make sure to always implement ",[155,413,414],{},"authorize"," in order to protect the server when it is exposed to a production environment.",[147,417,419],{"id":418},"storage-client","Storage Client",[143,421,422,423,426],{},"You can use the ",[389,424,425],{"href":75},"http driver"," to easily connect to the server.",[160,428,432],{"className":429,"code":430,"language":431,"meta":166,"style":166},"language-ts shiki shiki-themes github-light github-dark github-dark","import { createStorage } from \"unstorage\";\nimport httpDriver from \"unstorage\u002Fdrivers\u002Fhttp\";\n\nconst client = createStorage({\n  driver: httpDriver({\n    base: \"SERVER_ENDPOINT\",\n  }),\n});\nconst keys = await client.getKeys();\n","ts",[155,433,434,446,460,464,478,488,499,504,508],{"__ignoreMap":166},[170,435,436,438,440,442,444],{"class":172,"line":173},[170,437,177],{"class":176},[170,439,199],{"class":180},[170,441,184],{"class":176},[170,443,204],{"class":187},[170,445,191],{"class":180},[170,447,448,450,453,455,458],{"class":172,"line":194},[170,449,177],{"class":176},[170,451,452],{"class":180}," httpDriver ",[170,454,184],{"class":176},[170,456,457],{"class":187}," \"unstorage\u002Fdrivers\u002Fhttp\"",[170,459,191],{"class":180},[170,461,462],{"class":172,"line":209},[170,463,228],{"emptyLinePlaceholder":227},[170,465,466,468,471,473,475],{"class":172,"line":224},[170,467,234],{"class":176},[170,469,470],{"class":237}," client",[170,472,241],{"class":176},[170,474,245],{"class":244},[170,476,477],{"class":180},"({\n",[170,479,480,483,486],{"class":172,"line":231},[170,481,482],{"class":180},"  driver: ",[170,484,485],{"class":244},"httpDriver",[170,487,477],{"class":180},[170,489,490,493,496],{"class":172,"line":251},[170,491,492],{"class":180},"    base: ",[170,494,495],{"class":187},"\"SERVER_ENDPOINT\"",[170,497,498],{"class":180},",\n",[170,500,501],{"class":172,"line":267},[170,502,503],{"class":180},"  }),\n",[170,505,506],{"class":172,"line":283},[170,507,357],{"class":180},[170,509,510,512,515,517,520,523,526],{"class":172,"line":290},[170,511,234],{"class":176},[170,513,514],{"class":237}," keys",[170,516,241],{"class":176},[170,518,519],{"class":176}," await",[170,521,522],{"class":180}," client.",[170,524,525],{"class":244},"getKeys",[170,527,248],{"class":180},[147,529,531],{"id":530},"http-methods","HTTP Methods",[533,534,535,556,565,578],"ul",{},[536,537,538,541,542,545,546,549,550,545,553],"li",{},[155,539,540],{},"GET",": Maps to ",[155,543,544],{},"storage.getItem"," or ",[155,547,548],{},"storage.getKeys"," when the path ends with ",[155,551,552],{},"\u002F",[155,554,555],{},"\u002F:",[536,557,558,541,561,564],{},[155,559,560],{},"HEAD",[155,562,563],{},"storage.hasItem",". Returns 404 if not found.",[536,566,567,541,570,573,574,577],{},[155,568,569],{},"PUT",[155,571,572],{},"storage.setItem",". Value is read from the body and returns ",[155,575,576],{},"OK"," if the operation succeeded.",[536,579,580,541,583,545,586,549,589,545,591,593,594,577],{},[155,581,582],{},"DELETE",[155,584,585],{},"storage.removeItem",[155,587,588],{},"storage.clear",[155,590,552],{},[155,592,555],{},". Returns ",[155,595,576],{},[597,598,599],"note",{},[143,600,601,602,605,606,609,610,613],{},"When passing ",[155,603,604],{},"accept: application\u002Foctet-stream"," for GET and SET operations, the server switches to binary mode via ",[155,607,608],{},"getItemRaw"," and ",[155,611,612],{},"setItemRaw",".",[615,616,617],"style",{},"html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":166,"searchDepth":194,"depth":194,"links":619},[620,621,622],{"id":149,"depth":194,"text":150},{"id":418,"depth":194,"text":419},{"id":530,"depth":194,"text":531},"We can expose unstorage's instance to an HTTP server to allow remote connections.","md",{"icon":20},{"icon":20},{"title":17,"description":623},"B6M8J85gjcnfE-1zZXun55tLRXxfoe-5kDqGjkSCvTU",[630,632],{"title":12,"path":13,"stem":14,"description":631,"icon":15,"children":-1},"Unstorage exposes several utilities. You can individually import them and add only the needed bytes to your bundle.",{"title":22,"path":23,"stem":24,"description":633,"icon":25,"children":-1},"It is possible to extend unstorage by creating a custom driver.",1781217592757]