1+ package main
2+ import (
3+ "github.com/valyala/fasthttp"
4+ "log"
5+ "os"
6+ "strings"
7+ "bytes"
8+ "io/ioutil"
9+ "strconv"
10+ "time"
11+ "fmt"
12+ )
13+
14+ func download (url string ) bool {
15+ fileNames := strings .Split (url , "/" )
16+ fileName := fileNames [len (fileNames ) - 1 ]
17+ if fileName == "" {
18+ fileName = "noname"
19+ }
20+ out , _ := os .Create ("./download/" + fileName )
21+ defer out .Close ()
22+ statusCode , body , err := fasthttp .Get (nil , url )
23+ if statusCode == 200 && err == nil {
24+ out .Write (body )
25+ }
26+ return true
27+ }
28+
29+ func main () {
30+ m := func (ctx * fasthttp.RequestCtx ) {
31+ switch {
32+ case string (ctx .Path ()) == "/" :
33+ ctx .SetContentType ("text/html; charset=utf-8" )
34+ ctx .WriteString (`<!doctype html>
35+ <html class="no-js">
36+ <head>
37+ <meta charset="utf-8">
38+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
39+ <meta name="description" content="">
40+ <meta name="keywords" content="">
41+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
42+ <title>离线下载</title>
43+ <meta name="renderer" content="webkit">
44+ <meta http-equiv="Cache-Control" content="no-siteapp"/>
45+ <meta name="apple-mobile-web-app-capable" content="yes">
46+ <meta name="apple-mobile-web-app-status-bar-style" content="black">
47+ <meta name="apple-mobile-web-app-title" content="Amaze UI"/>
48+ <meta name="msapplication-TileColor" content="#0e90d2">
49+ <link rel="stylesheet" href="//cdn.amazeui.org/amazeui/2.4.2/css/amazeui.min.css">
50+ </head>
51+ <body>
52+ <header class="am-topbar am-topbar-inverse">
53+ <div class="am-container am-cf">
54+ <div class="am-g">
55+ <h1 class="am-topbar-brand">
56+ <a href="#">离线下载</a>
57+ </h1>
58+ <!-- topbar-right -->
59+ <div class="am-topbar-right">
60+ <button class="am-btn am-btn-primary am-topbar-btn am-btn-sm">基于golang的下载神器</button>
61+ </div>
62+ </div>
63+ </div>
64+
65+ </header>
66+
67+ <div class="am-container">
68+ <div class="am-g">
69+ <div class="am-u-md-10 am-u-sm-centered">
70+ <legend>离线下载</legend>
71+ <div class="am-form-group">
72+ <p>欢迎使用!采用golang后台下载的方法实现简单的离线下载功能</p>
73+ <p>文件永久保留,下载空间为512M,若空间不足,请手工删除,且用且珍惜!</p>
74+ <div class="am-input-group">
75+ <span class="am-input-group-label">
76+ <i class="am-icon-cloud-download"></i>
77+ </span>
78+ <input type="text" id="download" class="am-form-field" placeholder="请把文件的下载地址粘贴到这里,然后点击Enter即可。" />
79+ </div>
80+ </div>
81+ <button type="submit" class="am-btn am-btn-primary am-btn-block" onclick="download();">Enter</button>
82+ </div>
83+ </div>
84+ <div class="am-g">
85+ <div class="am-u-md-14 am-u-sm-centered">
86+ <table class="am-table am-table-hover">
87+ <thead>
88+ <tr>
89+ <th>文件列表</th>
90+ </tr>
91+ </thead>
92+ <tbody id="downlist">
93+
94+ </tbody>
95+ </table>
96+ </div>
97+ </div>
98+ <hr>
99+
100+ <!-- 多说评论框 start -->
101+ <div class="ds-thread" data-thread-key="c7ef117e8fb5d1de76d99897dbbdad64" data-title="php离线下载" data-url="http://lyxz.gq/"></div>
102+ <!-- 多说评论框 end -->
103+ <!-- 多说公共JS代码 start (一个网页只需插入一次) -->
104+ <script type="text/javascript">
105+ var duoshuoQuery = {short_name:"lyxzgq"};
106+ (function() {
107+ var ds = document.createElement('script');
108+ ds.type = 'text/javascript';ds.async = true;
109+ ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
110+ ds.charset = 'UTF-8';
111+ (document.getElementsByTagName('head')[0]
112+ || document.getElementsByTagName('body')[0]).appendChild(ds);
113+ })();
114+ </script>
115+ <!-- 多说公共JS代码 end -->
116+
117+ </div>
118+ <footer ata-am-widget="footer" class="am-footer am-footer-default" style="
119+ background:#555;
120+ font-color:#000;
121+ ">
122+ <style>
123+ .am-footer-default a{
124+ color:#999;
125+ }
126+ </style>
127+ <div class="am-footer-miscs">
128+ <p>友情链接 <a href="http://www.lanyus.com/" rel="friend" target="_blank">无心问世</a></p>
129+ <p><a href="https://github.com/ilanyu/offline-download" target="_blank">关于</a></p>
130+ <p class="am-article-meta">
131+ </p><p><a href="#" target="_blank"><span class="am-icon-qq am-success" target="_blank"></span> 程序开发 无心问世</a></p>
132+ <br>
133+ <p>© 2015 无心问世. copyright</p>
134+ </div>
135+ </footer>
136+
137+ <div class="am-modal am-modal-no-btn" tabindex="-1" id="downerror">
138+ <div class="am-modal-dialog">
139+ <div class="am-modal-hd">错误
140+ <a href="javascript: void(0)" class="am-close am-close-spin" data-am-modal-close>×</a>
141+ </div>
142+ <div class="am-modal-bd">
143+ 下载出现错误,可能是不允许的文件后缀或下载空间已满。
144+ </div>
145+ </div>
146+ </div>
147+
148+ <!--[if lt IE 9]>
149+ <script src="//libs.useso.com/js/jquery/1.11.1/jquery.min.js"></script>
150+ <script src="//cdn.staticfile.org/modernizr/2.8.3/modernizr.js"></script>
151+ <script src="/js/polyfill/rem.min.js"></script>
152+ <script src="//libs.useso.com/js/respond.js/1.4.2/respond.min.js"></script>
153+ <script src="//cdn.amazeui.org/amazeui/2.4.2/js/amazeui.legacy.min.js"></script>
154+ <![endif]-->
155+
156+ <!--[if (gte IE 9)|!(IE)]><!-->
157+ <script src="//libs.useso.com/js/jquery/2.1.1/jquery.min.js"></script>
158+ <script src="//cdn.amazeui.org/amazeui/2.4.2/js/amazeui.min.js"></script>
159+ <!--<![endif]-->
160+ <script>
161+ function writeDownList() {
162+ $.getJSON('./downlist',null,function (data) {
163+ var downlist = document.getElementById('downlist');
164+ downlist.innerHTML = '<tr><td>#</td><td>名称</td><td>修改时间</td><td>大小</td><td>操作</td></tr>';
165+ for (var i = 0 ; i < data.length ; i++) {
166+ downlist.innerHTML = downlist.innerHTML + '<tr><td>' + i + '</td><td><a href="./download/' + data[i]['name'] + '">' + data[i]['name'] + '</a></td><td>' + data[i]['mtime'] + '</td><td>' + data[i]['size'] + '</td><td><button type="button" class="am-btn" onclick="del(\'' + data[i]['name'] + '\');">删除</button></td></tr>';
167+ }
168+ });
169+ }
170+ function download() {
171+ var url = document.getElementById("download").value;
172+ $.get('./down',{'url':url},function (data) {
173+ if (data == 'success') {
174+ writeDownList();
175+ } else {
176+ $('#downerror').modal();
177+ }
178+ });
179+ }
180+ function del(file) {
181+ $.get('./delete',{'file':file},function (data) {
182+ writeDownList();
183+ });
184+ }
185+ writeDownList();
186+ </script>
187+ </body>
188+ </html>
189+ ` )
190+ case string (ctx .Path ()) == "/down" :
191+ args := ctx .QueryArgs ()
192+ url := string (args .Peek ("url" ))
193+ protocol := strings .Split (url , "://" )
194+ if protocol [0 ] != "http" && protocol [0 ] != "https" && protocol [0 ] != "ftp" {
195+ ctx .WriteString ("failed" )
196+ log .Println (protocol )
197+ return
198+ }
199+ go download (url )
200+ ctx .WriteString ("success" )
201+ log .Println ("visiter " + ctx .RemoteIP ().String () + " use " + string (ctx .UserAgent ()) + " downloaded " + url + " in " + time .Now ().Format ("2006-01-02 15:04:05" ))
202+ case string (ctx .Path ()) == "/delete" :
203+ args := ctx .QueryArgs ()
204+ file := string (args .Peek ("file" ))
205+ file = strings .Replace (file , "/" , "" , - 1 )
206+ os .Remove ("./download/" + file )
207+ ctx .WriteString ("success" )
208+ case bytes .HasPrefix (ctx .Path (), []byte ("/download/" )):
209+ fasthttp .FSHandler ("./download/" , 1 )(ctx )
210+ case string (ctx .Path ()) == "/downlist" :
211+ dirList , _ := ioutil .ReadDir ("./download/" )
212+ length := len (dirList )
213+ ctx .WriteString ("[" )
214+ for i := 0 ; i < length ; i ++ {
215+ ctx .WriteString (`{"name":"` + dirList [i ].Name () + `","mtime":"` + dirList [i ].ModTime ().Format ("2006-01-02 15:04:05" ) + `","size":"` + strconv .FormatInt (dirList [i ].Size (), 10 ) + ` B"}` )
216+ if i != length - 1 {
217+ ctx .WriteString ("," )
218+ }
219+ }
220+ ctx .WriteString ("]" )
221+ default :
222+ ctx .Error ("not found" , fasthttp .StatusNotFound )
223+ }
224+ }
225+ if fileInfo , err := os .Stat ("./download" ); err != nil || ! fileInfo .IsDir () {
226+ os .Mkdir ("./download" , 0755 )
227+ log .Println ("mkDir ./download" )
228+ }
229+ bind := fmt .Sprintf ("%s:%s" , os .Getenv ("OPENSHIFT_GO_IP" ), os .Getenv ("OPENSHIFT_GO_PORT" ))
230+ log .Printf ("listening on %s...\n " , bind )
231+ if err := fasthttp .ListenAndServe (bind , m ); err != nil {
232+ log .Fatal (err )
233+ }
234+ }
0 commit comments