1 Star 0 Fork 0

liuyidana/WeiXinstudy

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
httpserver.js 4.61 KB
一键复制 编辑 原始数据 按行查看 历史
liuyidana 提交于 2021-11-21 10:06 . --
'use strict'
const http = require('http')
const fs = require('fs')
const fsp = fs.promises
function parseBodyHeaders(data) {
let headers = {}
let dsplit = data.split('\r\n').filter(p => p.length > 0)
let ind
let k
for (let d of dsplit) {
ind = d.indexOf(':')
if (ind <= 0) continue
k = d.substring(0, ind).toLowerCase()
headers[k] = d.substring(ind+1).trim()
}
let cpd = headers['content-disposition']
//按照; 分割成数组,第一个元素form-data去掉
let clist = cpd.split('; ').slice(1)
let name, filename
for (let a of clist) {
ind = a.indexOf('filename="')
if (ind >= 0) {
filename = a.substring(ind+10, a.length-1)
} else {
name = a.substring(6, a.length - 1)
}
}
return {
headers,
name,
filename
}
}
/**
*
* @param {Buffer} bodyData 原始的Body数据
* @param {Object} reqHeaders reuqest.headers
*/
function parseBody(bodyData, reqHeaders) {
//content-type: multipart/form-data; boundary=-----34294329
let ctype = reqHeaders['content-type']
//拿到分界线boundary
let bdy = ctype.substring( ctype.indexOf('=')+1 )
//数据中用于分割文件的分界线
//let bdy = `--${bdy}\r\n`
let crlf_bdy = `\r\n--${bdy}`
//从偏移bdy的长度开始查找下一个分界线的位置
let data_end_index = bodyData.indexOf(crlf_bdy, crlf_bdy.length)
//body消息数据中header部分的最后索引
let header_end_index = bodyData.indexOf('\r\n\r\n', crlf_bdy.length)
let header_data = bodyData.toString('utf8',
crlf_bdy.length,
header_end_index);
//解析body数据中的消息头
let hd = parseBodyHeaders(header_data)
let fileinfo = {
start: header_end_index+4,
end: data_end_index,
}
fileinfo.length = fileinfo.end - fileinfo.start
return {
name: hd.name,
filename: hd.filename,
headers: hd.headers,
start: fileinfo.start,
end: fileinfo.end,
length: fileinfo.length
}
}
function parseExtName (filename) {
if (filename.length < 2) return ''
let namesplit = filename.split('.')
.filter(p => p.length > 0)
if (namesplit.length < 2) return '';
return `.${namesplit[ namesplit.length - 1 ]}`
}
let routerTable = {
GET: {
'/upload' : async (ctx) => {
let stm = fs.createReadStream('./upload.html')
stm.pipe(ctx.res)
stm.on('end', () => {
ctx.end()
})
}
},
POST: {
'/upload' : async (ctx) => {
console.log(ctx.files)
let finfo = ctx.files
let filename = `${Date.now()}-`
+ `${parseInt(Math.random() * 100000) + 100000}`
+ parseExtName(finfo.filename)
let fh = await fsp.open(filename, 'w+')
let fret = await fh.write(ctx.rawBody,
finfo.start,
finfo.length,
0)
//关闭打开的文件
fh.close()
//返回写入的字节数。string或buffer类型,不能是其他类型。
ctx.end( `${fret.bytesWritten}` )
}
}
}
/** ------------------- START SERVER -------------------- */
let serv = http.createServer()
serv.on('request', (request, response) => {
let rm = routerTable[request.method]
//根据?切分字符串
let usplit = request.url.split('?')
let pathname = usplit[0]
let querystring = usplit[1] || ''
if (!rm || !rm[ pathname ]) {
response.statusCode = 404
response.end('page not found')
return
}
//ctx is context, 创建请求上下文对象。
let ctx = {
req: request,
res: response,
method: request.method,
headers: request.headers,
end: (data, encoding='utf8') => {
response.end(data, encoding)
},
write: (data, encoding='utf8') => {
response.write(data, encoding)
},
path: pathname,
querystring: querystring,
rawBody: null,
}
let bufferList = []
let totalLength = 0
if ('PD'.indexOf(request.method[0]) >= 0) {
request.on('data', chunk => {
totalLength += chunk.length
bufferList.push(chunk)
})
} else {
request.on('data', chunk => {
response.statusCode = 400
response.end()
})
}
request.on('end', () => {
if (bufferList.length > 0) {
ctx.rawBody = Buffer.concat(bufferList, totalLength)
bufferList = []
}
let ctype = ctx.headers['content-type'] || ''
if (ctx.rawBody && ctype.indexOf('multipart/form-data') === 0)
{
ctx.files = parseBody(ctx.rawBody, ctx.headers)
}
rm[ pathname ](ctx)
})
})
serv.listen(3456)
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/liuyidana/wei-xinstudy.git
git@gitee.com:liuyidana/wei-xinstudy.git
liuyidana
wei-xinstudy
WeiXinstudy
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385