阿里云esc建设网站,国外网站怎么打开,做网站创意,鞍山钟点工招聘信息wmproxy
wmproxy是由Rust编写#xff0c;已实现http/https代理#xff0c;socks5代理#xff0c; 反向代理#xff0c;静态文件服务器#xff0c;内网穿透#xff0c;配置热更新等#xff0c; 后续将实现websocket代理等#xff0c;同时会将实现过程分享出来#xff…wmproxy
wmproxy是由Rust编写已实现http/https代理socks5代理 反向代理静态文件服务器内网穿透配置热更新等 后续将实现websocket代理等同时会将实现过程分享出来 感兴趣的可以一起造个轮子法
项目 wmproxy
gite: https://gitee.com/tickbh/wmproxy
github: https://github.com/tickbh/wmproxy
HTTP文件服务器的意义
HTTP文件服务器的意义是可以放置网站文件可以放置数据文件。 HTTP服务器一般指网站服务器是指驻留于因特网上某种类型计算机的程序可以处理浏览器等Web客户端的请求并返回相应响应。 当前大量的应用会依赖到文件服务器比如我们非常熟悉的网站会加载index.html)文件及各种css及js文件比如我们的各种APP会有相对应的版本信息会有相应的版本文件又或者小程序本身就是一个可执行文件当你点击的时候应用去下载相应的小程序文件然后在本地进行加载然后打开提供服务。目前我们的互联网上冲浪完全无法离开文件服务器。
HTTP文件服务器几大作用
1. 文件共享 文件服务器的主要功能是提供文件共享功能。它允许用户从他们自己的计算机或设备访问共享文件和文件夹而不管他们的物理位置。用户可以查看、编辑和保存存储在服务器上的文件所有有权访问该文件的用户都会自动更新更改。 以下是我们在聊天软件上发送一张图片给另一个人的流程 #mermaid-svg-WnNcFdeFlQ2TgxCl {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .error-icon{fill:#552222;}#mermaid-svg-WnNcFdeFlQ2TgxCl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WnNcFdeFlQ2TgxCl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .marker.cross{stroke:#333333;}#mermaid-svg-WnNcFdeFlQ2TgxCl svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WnNcFdeFlQ2TgxCl .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .cluster-label text{fill:#333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .cluster-label span{color:#333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .label text,#mermaid-svg-WnNcFdeFlQ2TgxCl span{fill:#333;color:#333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .node rect,#mermaid-svg-WnNcFdeFlQ2TgxCl .node circle,#mermaid-svg-WnNcFdeFlQ2TgxCl .node ellipse,#mermaid-svg-WnNcFdeFlQ2TgxCl .node polygon,#mermaid-svg-WnNcFdeFlQ2TgxCl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WnNcFdeFlQ2TgxCl .node .label{text-align:center;}#mermaid-svg-WnNcFdeFlQ2TgxCl .node.clickable{cursor:pointer;}#mermaid-svg-WnNcFdeFlQ2TgxCl .arrowheadPath{fill:#333333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WnNcFdeFlQ2TgxCl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-WnNcFdeFlQ2TgxCl .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-WnNcFdeFlQ2TgxCl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WnNcFdeFlQ2TgxCl .cluster text{fill:#333;}#mermaid-svg-WnNcFdeFlQ2TgxCl .cluster span{color:#333;}#mermaid-svg-WnNcFdeFlQ2TgxCl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WnNcFdeFlQ2TgxCl :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 将图片共享 将图片上传 返回图片地址 将图片地址推送给 将地址通知给 从文件服务器中获取图片 你 APP 文件服务器 APP服务器 聊天对象 2. 集中存储 此时你的不小心将数据删除此时你想找回原来的图片以下是整个过程 #mermaid-svg-eF5UxXcI7K8jSH9f {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-eF5UxXcI7K8jSH9f .error-icon{fill:#552222;}#mermaid-svg-eF5UxXcI7K8jSH9f .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eF5UxXcI7K8jSH9f .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-eF5UxXcI7K8jSH9f .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eF5UxXcI7K8jSH9f .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eF5UxXcI7K8jSH9f .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eF5UxXcI7K8jSH9f .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eF5UxXcI7K8jSH9f .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eF5UxXcI7K8jSH9f .marker.cross{stroke:#333333;}#mermaid-svg-eF5UxXcI7K8jSH9f svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eF5UxXcI7K8jSH9f .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-eF5UxXcI7K8jSH9f .cluster-label text{fill:#333;}#mermaid-svg-eF5UxXcI7K8jSH9f .cluster-label span{color:#333;}#mermaid-svg-eF5UxXcI7K8jSH9f .label text,#mermaid-svg-eF5UxXcI7K8jSH9f span{fill:#333;color:#333;}#mermaid-svg-eF5UxXcI7K8jSH9f .node rect,#mermaid-svg-eF5UxXcI7K8jSH9f .node circle,#mermaid-svg-eF5UxXcI7K8jSH9f .node ellipse,#mermaid-svg-eF5UxXcI7K8jSH9f .node polygon,#mermaid-svg-eF5UxXcI7K8jSH9f .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eF5UxXcI7K8jSH9f .node .label{text-align:center;}#mermaid-svg-eF5UxXcI7K8jSH9f .node.clickable{cursor:pointer;}#mermaid-svg-eF5UxXcI7K8jSH9f .arrowheadPath{fill:#333333;}#mermaid-svg-eF5UxXcI7K8jSH9f .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eF5UxXcI7K8jSH9f .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eF5UxXcI7K8jSH9f .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-eF5UxXcI7K8jSH9f .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-eF5UxXcI7K8jSH9f .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eF5UxXcI7K8jSH9f .cluster text{fill:#333;}#mermaid-svg-eF5UxXcI7K8jSH9f .cluster span{color:#333;}#mermaid-svg-eF5UxXcI7K8jSH9f div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eF5UxXcI7K8jSH9f :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 同步旧的聊天记录, 获取图片地址 重新下载图片 获取完图片后推送给 你 APP 文件服务器 APP服务器 此时文件服务器担任着集中存储的角色海量的数据将汇聚在中心服务器上我们可以通过网络访问到海量的数据资源。 3. 备份与恢复 上述过程相当于服务器帮你备份了图片数据在你不小心丢失的时候可以恢复您的数据我们最经常使用的如图片备份到网盘一方面可以释放掉本地的空间另一方面我们可以将数据保存到很久之后。 4. 访问控制 我们在获取到图片地址的时候并不是任何的角色都可以获取到该图片的资源在服务器内部中会有相关的权限验证在为您提供数据的同时并保护着您的数据安全。
file_server文件服务器
一个静态文件服务器支持真实和虚拟文件系统。它通过将请求的URI路径附加到站点的根路径来形成文件路径。 最常见的是file_server指令与root指令配对为整个网站设置文件根。其中保证所有的访问仅能在root指定的目录之下不能访问其上级的任何数据故在root下的目录理论上即使禁目录访问也可能被全部访问到暴力遍历但在root上级的目录不可能被以任何的方式进行访问即使添加../相对路径也不行。
file_server参数相关
结构定义如下
pub struct FileServer {#[serde(default default_root)]pub root: String,#[serde(default)]pub prefix: String,#[serde(defaultdefault_hide)]pub hide: VecString,#[serde(default default_index)]pub index: VecString,#[serde(default default_status)]pub status: u16,#[serde(default default_precompressed)]pub precompressed: VecString,#[serde(default)]pub disable_compress: bool,#[serde(default default_bool_true)]pub browse: bool,
}browse 对没有索引文件的目录的请求当前又是一个目录的情况下启用文件列表。root 设置网站根目录。指向的是当前文件磁盘下的路径前缀如/file/那么提供服务的将是/file/的文件服务prefix Url的前缀如/static/如果我们获取到一个请求路径如/static/src/wmproxy.md那么我们会去掉前缀得到src/wmproxy.md那么实际的指向为/file/src/wmproxy.md进行文件服务hide 是一个要隐藏的文件或文件夹的列表如果要求文件服务器将假装它们不存在。该指令接受占位符和glob模式。注意这些是 文件系统 路径不是请求路径。换句话说相对路径使用当前工作目录作为基础而不是网站根目录所有的路径在比较之前都会被转换为绝对形式如果可能的话。指定一个没有路径分隔符的文件名或模式将隐藏所有具有匹配名称的文件无论其位置如何index 是一个寻找索引文件的文件名列表。默认index.html index.htm。precompressed 是用于搜索预压缩挎包文件的编码格式列表。支持的格式有gzip.gz和br.br。所有的文件查找将首先寻找未压缩文件的存在。一旦找到我们将以未添加之前的格式做mimetype如README.md.gz取的是md的mimetype也就是text/plain。并适当地设置Content-Encoding响应头。否则将以正常的未压缩文件进行响应。如果encode指令被启用那么如果没有预压缩它可能会对响应进行即时压缩。如我们访问README.md但此时目录下存在README.md.gz那我们我们响应的是gz的文件并设置Content-Encoding: gzip如此做的好处我们对该文件的任何请求我们都无须耗任何压缩的时间响应更快我们可以用更高的压缩比来进行预压缩可节省更多时间。status 是一个可选的状态代码覆盖在编写响应时使用。在用自定义错误页面响应请求时特别有用。可以是一个3位数的状态代码例如404。支持占位符。默认情况下写入的状态代码通常是200或206用于部分内容。
当前目录外的静态文件服务器。
reverse:file_server:启用了文件列表:
reverse:file_server:browse: true只服务于/static文件夹中的静态文件:
reverse:file_server:root: /static/browse: true隐藏所有.git文件夹及其内容。
reverse:file_server:root: /static/browse: truehide: [.git]如果客户端支持Accept-Encoding头发送gzip,br则检查请求的文件是否存在预压缩的文件。因此如果/path/to/file被请求/path/to/file.br和/path/to/file.gz并提供第一个具有相应内容编码的可用文件。
reverse:file_server:root: /static/browse: truehide: [.git]precompressed: [br, gzip]mimetype作用
多用途互联网邮件扩展MIMEMultipurpose Internet Mail Extensions是一个 互联网标准它扩展了 电子邮件标准使其能够支持非 ASCII字符、 二进制格式附件等多种格式的邮件消息。 内容类型Content-Type这个头部领域用于指定消息的类型。一般以下面的形式出现。[type]/[subtype] type有下面的形式。 Text用于标准化地表示的文本信息文本消息可以是多种字符集和或者多种格式的 Multipart用于连接消息体的多个部分构成一个消息这些部分可以是不同类型的数据 Application用于传输应用程序数据或者二进制数据 Message用于包装一个E-mail消息 Image用于传输静态图片数据 Audio用于传输音频或者音声数据 Video用于传输动态影像数据可以是与音频编辑在一起的视频数据格式。 subtype用于指定type的详细形式。type/subtype配对的集合和与此相关的参数将随着时间而增长。为了确保这些值在一个有序而且公开的状态下开发MIME使用Internet Assigned Numbers Authority (IANA)作为中心的注册机制来管理这些值。常用的subtype值如下所示 text/plain纯文本text/htmlHTML文档application/xhtmlxmlXHTML文档image/gifGIF图像image/jpegJPEG图像image/pngPNG图像video/mpegMPEG动画application/octet-stream任意的二进制数据application/pdfPDF文档application/mswordMicrosoft Word文件message/rfc822 RFC 822形式multipart/alternativeHTML邮件的HTML形式和纯文本形式相同内容使用不同形式表示application/x-www-form-urlencoded使用HTTP的POST方法提交的表单multipart/form-data同上但主要用于表单提交时伴随文件上传的场合
我们根据现有的已知的我们用了静态变量做了以下数据定义后续将会进行数据补充或者自定义
lazy_static! {static ref DEFAULT_MIMETYPE: HashMapstatic str, static str {let mut m HashMap::static str, static str::new();m.insert(doc, application/msword);m.insert(pdf, application/pdf);m.insert(rtf, application/rtf);m.insert(xls, application/vnd.ms-excel);m.insert(ppt, application/vnd.ms-powerpoint);m.insert(rar, application/application/x-rar-compressed);m.insert(swf, application/x-shockwave-flash);m.insert(zip, application/zip);m.insert(json, application/json);m.insert(yaml, text/plain);m.insert(mid, audio/midi);m.insert(midi, audio/midi);m.insert(kar, audio/midi);m.insert(mp3, audio/mpeg);m.insert(ogg, audio/ogg);m.insert(m4a, audio/m4a);m.insert(ra, audio/x-realaudio);m.insert(gif, image/gif);m.insert(jpeg, image/jpeg);m.insert(jpg, image/jpeg);m.insert(png, image/png);m.insert(tif, image/tiff);m.insert(tiff, image/tiff);m.insert(wbmp, image/vnd.wap.wbmp);m.insert(ico, image/x-icon);m.insert(jng, image/x-jng);m.insert(bmp, image/x-ms-bmp);m.insert(svg, image/svgxml);m.insert(svgz, image/svgxml);m.insert(webp, image/webp);m.insert(svg, image/svgxml);m.insert(css, text/css);m.insert(html, text/html);m.insert(htm, text/html);m.insert(shtml, text/html);m.insert(txt, text/plain);m.insert(md, text/plain);m.insert(xml, text/xml);m.insert(3gpp, video/3gpp);m.insert(3gp, video/3gpp);m.insert(mp4, video/mp4);m.insert(mpeg, video/mpeg);m.insert(mpg, video/mpeg);m.insert(mov, video/quicktime);m.insert(webm, video/webm);m.insert(flv, video/x-flv);m.insert(m4v, video/x-m4v);m.insert(wmv, video/x-ms-wmv);m.insert(avi, video/x-msvideo);m};
}源码实现 源码主要实现在file_server.rs的deal_request函数。节选 pub async fn deal_request(self,req: RequestRecvStream,
) - ProtResultResponseRecvStream {let path req.path().clone();// 无效前缀无法处理if !path.starts_with(self.prefix) {return Ok(self.ret_error_msg(unknow path));}let root_path Path::new(self.root);let mut real_path Path::new(real_path).to_owned();// 必须保证不会跑出root设置的目录之外如故意访问../之类的if !real_path.starts_with(root_path) || self.is_hide_path(root_path.as_ref()) {return Ok(self.ret_error_msg(cant view parent file));}// 访问路径是目录尝试是否有index的文件如果有还是以文件访问if real_path.is_dir() {for index in self.index {let new_path real_path.join(index);if new_path.exists() {real_path new_path;break;}}}// 访问为目录如果启用目录访问则返回当前的文件夹的内容if real_path.is_dir() {if !self.browse {return Ok(self.ret_error_msg(cant view parent file));}let mut binary BinaryMut::new();// ... let recv RecvStream::only(binary.freeze());let builder Response::builder().version(req.version().clone());let mut response builder.header(HeaderName::CONTENT_TYPE, text/html; charsetutf-8).body(recv).map_err(|_err| io::Error::new(io::ErrorKind::Other, ))?;if self.disable_compress {response.headers_mut().insert(HeaderName::CONTENT_ENCODING, );}return Ok(response);} else {// 访问为文件判断当前的后缀返回合适的mimetype如果有合适的预压缩文件也及时返回if self.is_hide_path(path.as_ref()) {return Ok(self.ret_error_msg(cant view file));}// 获取后缀let extension if let Some(s) real_path.extension() {s.to_string_lossy().to_string()} else {String::new()};let application DEFAULT_MIMETYPE.get(*extension).unwrap_or();//查找是否有合适的预压缩文件if let Some(accept) req.headers().get_option_value(HeaderName::ACCEPT_ENCODING) {for pre in self.precompressed {// 得客户端发送支持该格式if !accept.contains(pre.as_bytes()) {continue;}let mut new real_path.clone();new.as_mut_os_string().push(.);match **pre {gzip new.as_mut_os_string().push(gz),br new.as_mut_os_string().push(br),_ continue,};// 如果预压缩文件存在if new.exists() {println!(convert to new file {}, new.to_string_lossy());let file File::open(new).await?;let mut recv RecvStream::new_file(file, BinaryMut::new(), false);match **pre {gzip recv.set_compress_origin_gzip(),br recv.set_compress_brotli(),_ unreachable!(),}// ...return Ok(response);}}}if !real_path.exists() {return Ok(self.ret_error_msg(cant view file));}// ...return Ok(response);}
}结语 如此静态文件服务器则已初步实现文件服务中的压缩及流式传输已基本完成