master
宇天 2022-04-09 20:26:23 +08:00
commit 89d6c5a332
9 changed files with 315 additions and 0 deletions

18
.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
package-lock.json
node_modules
.vscode-test
out.js
*.vsix
*.css

10
.prettierrc.yaml Normal file
View File

@ -0,0 +1,10 @@
jsxBracketSameLine: true
jsxSingleQuote: true
semi: false
singleQuote: true
printWidth: 100
useTabs: false
tabWidth: 2
trailingComma: none
bracketSpacing: true
arrowParens: avoid

28
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,28 @@
// A launch configuration that launches the extension inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
]
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/test/suite/index"
]
}
]
}

10
.vscodeignore Normal file
View File

@ -0,0 +1,10 @@
.vscode/**
.vscode-test/**
node_modules/**
test/**
package-lock.json
.travis.yml
.gitignore
index.js
test.js

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
README.md Normal file
View File

@ -0,0 +1,25 @@
# simple.http
> 🔥 简单的http服务器, 方便临时调试html。
[![Version](https://vsmarketplacebadge.apphb.com/version-short/yutent.simple.http.svg)](https://marketplace.visualstudio.com/items?itemName=yutent.simple.http)
[![Rating](https://vsmarketplacebadge.apphb.com/rating-short/yutent.simple.http.svg)](https://marketplace.visualstudio.com/items?itemName=yutent.simple.http)
[![Installs](https://vsmarketplacebadge.apphb.com/installs/yutent.simple.http.svg)](https://marketplace.visualstudio.com/items?itemName=yutent.simple.http)
## 插件说明
> 这插件只是应一个基友需求, 临时写的。如果你有其他的功能需求, 请在插件商店中`搜索其他插件`。
## 插件使用
> 在项目根目录中放置 `.httpserver`文件, 并配置好之后, 重启或重新加载窗口, 以启动服务。
## .httpserver 文件
> 使用`.httpserver`来配置web服务器信息, 该文件应为一个json格式的。
```json
{
"port": 23333, // 默认使用 23333 端口, 如果被使用了, 会向上查找可用端口
"enabled": true // 这里配置为 true 才会启动web服务
}
```

146
index.js Normal file
View File

@ -0,0 +1,146 @@
/**
*
* @author yutent<yutent.io@gmail.com>
* @date 2022/04/09 18:26:35
*/
const vsc = require('vscode')
const { join } = require('path')
const { parse } = require('url')
const http = require('http')
const fs = require('iofs')
const std = vsc.window.createOutputChannel('http.server')
const decode = decodeURIComponent
const MIME_TYPES = {
html: 'text/html;charset=utf-8',
txt: 'text/plain;charset=utf-8',
css: 'text/css;charset=utf-8',
xml: 'text/xml;charset=utf-8',
gif: 'image/gif',
jpg: 'image/jpeg',
webp: 'image/webp',
tiff: 'image/tiff',
png: 'image/png',
svg: 'image/svg+xml',
ico: 'image/x-icon',
bmp: 'image/x-ms-bmp',
js: 'application/javascript;charset=utf-8',
json: 'application/json;charset=utf-8',
mp3: 'audio/mpeg',
ogg: 'audio/ogg',
m4a: 'audio/x-m4a',
mp4: 'video/mp4',
webm: 'video/webm',
ttf: 'font/font-ttf',
woff: 'font/font-woff',
woff2: 'font/font-woff2',
other: 'application/octet-stream'
}
MIME_TYPES.htm = MIME_TYPES.html
MIME_TYPES.jpeg = MIME_TYPES.jpg
MIME_TYPES.tif = MIME_TYPES.tiff
let root
let enabled = false
let port = 23333
let baseUrl = 'http://127.0.0.1:' + port
std.out = function (...args) {
std.appendLine('[simple.http]: ' + args.join(' '))
}
function createServer() {
if (port > 65535) {
std.out('端口超出有效范围0-65535, 当前为: ' + port)
enabled = false
return
}
std.out(`尝试使用${port}端口...`)
http
.createServer(function (req, res) {
let pathname = parse(req.url)
.pathname.slice(1)
.replace(/[\/]+$/, '')
pathname = decode(pathname) || 'index.html'
let file = join(root, pathname)
let stat = fs.stat(file)
let ext = pathname.split('.').pop()
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader('Access-Control-Allow-Headers', '*')
res.setHeader('Cache-Control', 'no-store')
res.setHeader('X-Powered-By', 'VS Code simple.http')
if (stat.isFile()) {
res.setHeader('Accept-Ranges', 'bytes')
res.setHeader('Content-Type', MIME_TYPES[ext] || MIME_TYPES.other)
res.setHeader('Content-Length', stat.size)
res.writeHead(200, 'OK')
fs.origin.createReadStream(file).pipe(res)
} else {
res.setHeader('Content-Type', MIME_TYPES.html)
res.setHeader('Content-Length', 0)
res.writeHead(404, 'Not Found')
res.end('')
}
})
.listen(port)
.on('error', err => {
std.out(`${port}端口被占用~~~`)
port++
createServer()
})
.on('listening', _ => {
baseUrl = 'http://127.0.0.1:' + port
std.out('启动成功, 请访问', baseUrl)
})
}
function __init__() {
let folders = vsc.workspace.workspaceFolders
if (folders && folders.length) {
root = folders[0].uri.fsPath
}
if (root) {
let file = join(root, '.httpserver')
//
if (fs.isfile(file)) {
let conf = JSON.parse(fs.cat(file).toString())
if (conf.enabled) {
enabled = true
port = conf.port || 23333
createServer()
} else {
std.out('发现配置文件, 但服务为 关闭状态')
}
}
}
}
function deactivate() {}
exports.activate = function (ctx) {
__init__()
let cmd = vsc.commands.registerCommand('HttpServer.open', _ => {
if (enabled) {
let editor = vsc.window.activeTextEditor
if (editor) {
console.log(editor)
let pathname = editor.document.uri.fsPath.slice(root.length)
vsc.commands.executeCommand('vscode.open', baseUrl + pathname)
}
}
})
ctx.subscriptions.push(cmd)
}
exports.deactivate = deactivate

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

57
package.json Normal file
View File

@ -0,0 +1,57 @@
{
"name": "simple.http",
"displayName": "simple.http",
"description": "🔥 简单的http服务器, 方便临时调试html",
"version": "1.0.0",
"publisher": "yutent",
"author": "Yutent [@yutent]",
"icon": "logo.png",
"engines": {
"vscode": "^1.28.0"
},
"categories": [
"Other"
],
"activationEvents": [
"*"
],
"main": "out.js",
"contributes": {
"commands": [
{
"command": "HttpServer.open",
"title": "在浏览器中打开"
}
],
"menus": {
"editor/context": [
{
"when": "!inOutput",
"command": "HttpServer.open",
"title": "在浏览器中打开"
}
]
}
},
"repository": {
"type": "git",
"url": "https://github.com/yutent/http.server.git"
},
"keywords": [
"http.server",
"http server",
"simple http",
"yutent"
],
"scripts": {
"start": "esbuild index.js --bundle --outfile=out.js --external:vscode --format=cjs --platform=node",
"pack": "npm start -- --minify"
},
"license": "MIT",
"dependencies": {
"iofs": "^1.5.0"
},
"devDependencies": {
"esbuild": "^0.12.14"
}
}