public_handers.go
package manager
import (
"net/http"
"regexp"
"strconv"
"io"
"strings"
"fmt"
"time"
)
var publicUrlRegex *regexp.Regexp
func init() {
var err error
publicUrlRegex, err = regexp.Compile("/([0-9]*)/([0-9]*)/(.*)")
if err != nil {
panic(err)
}
}
//公共资源处理器
func (vm *VolumeManager)publicEntry(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet, http.MethodHead:
if publicUrlRegex.MatchString(r.URL.Path) {
vm.publicReadFile(w, r)
} else {
http.NotFound(w, r)
}
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
//读取公共资源文件
func (vm *VolumeManager)publicReadFile(w http.ResponseWriter, r *http.Request) {
match := publicUrlRegex.FindStringSubmatch(r.URL.Path)
vid, _ := strconv.ParseUint(match[1], 10, 64)
volume := vm.Volumes[vid]
if volume == nil {
http.Error(w, "can't find volume", http.StatusNotFound)
return
}
fid, _ := strconv.ParseUint(match[2], 10, 64)
file, err := volume.Get(fid)
if err != nil || file.Info.FileName != match[3] {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", get_content_type(file.Info.FileName))
w.Header().Set("Accept-Ranges", "bytes")
w.Header().Set("ETag", fmt.Sprintf("\"%d\"", fid))
//暂时不使用Last-Modified,用ETag即可
//w.Header().Set("Last-Modified", file.Info.Mtime.Format(http.TimeFormat))
w.Header().Set("Expires", time.Now().In(time.UTC).Add(DefaultExpires).Format(http.TimeFormat))
etagMatch := false
if r.Header.Get("If-None-Match") != "" {
s := r.Header.Get("If-None-Match")
if etag, err := strconv.ParseUint(s[1:len(s) - 1], 10, 64); err == nil && etag == fid {
etagMatch = true
}
}
if r.Header.Get("Range") != "" {
ranges := strings.Split(r.Header.Get("Range")[6:], "-")
start, err := strconv.ParseUint(ranges[0], 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
length := uint64(0)
if start > file.Info.Size {
start = file.Info.Size
} else if ranges[1] != "" {
end, err := strconv.ParseUint(ranges[1], 10, 64)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
end += 1
if end > file.Info.Size {
end = file.Info.Size
}
length = end - start
} else {
length = file.Info.Size - start
}
w.Header().Set("Content-Length", strconv.FormatUint(length, 10))
if length == 0 {
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
return
}
w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, start + length - 1, file.Info.Size))
if etagMatch {
w.WriteHeader(http.StatusNotModified)
return
}
w.WriteHeader(http.StatusPartialContent)
if r.Method != http.MethodHead {
file.Seek(int64(start), 0)
io.CopyN(w, file, int64(length))
}
} else {
w.Header().Set("Content-Length", strconv.FormatUint(file.Info.Size, 10))
if etagMatch {
w.WriteHeader(http.StatusNotModified)
} else if r.Method != http.MethodHead {
io.Copy(w, file)
}
}
}
public_handers.go的更多相关文章
随机推荐
- Oracle12c(12.1)中性能优化&功能增强之通过参数THREADED_EXECTION使用多线程模型
1. 后台 UNIX/Linux系统上,oracle用多进程模型.例如:linux上一个常规安装的数据库会有如下进程列: $ ps -ef | grep [o]ra_ oracle 15356 ...
- java小知识点汇总
1.ConcurrentHashMap使用segment来分段和管理锁,segment继承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock来保证线程安 ...
- Memcache架构新思考
2011年初Marc Kwiatkowski通过Memecache@Facebook介绍了Facebook的Memcache架构,现在重新审视这个架构,仍有很多方面在业界保持先进性.作为weibo内部 ...
- Day15 jss整体结构梳理
JS DOM--- 两个步骤: 1 查找标签 (1)直接查找 document.getElementById("idname") // dom对象 document.getElem ...
- 对比Cassandra、 Mongodb、CouchDB、Redis、Riak、 Membase、Neo4j、HBase
转自:http://www.cnblogs.com/alephsoul-alephsoul/archive/2013/04/26/3044630.html 导读:Kristóf Kovács 是一位软 ...
- Python flask中的配置
当你开始学习Flask时,配置看上去是小菜一碟.你仅仅需要在config.py定义几个变量,然后万事大吉. 然而当你不得不管理一个生产上的应用的配置时,这一切将变得棘手万分. 你不得不设法保护API密 ...
- C# 获取文件下载的各种方法
public class RemoteDownload { public static void DownLoad(string addressUrl,string localName) { //下载 ...
- 蚂蚁 RPC 框架 SOFA-RPC 初体验
前言 最近蚂蚁金服开源了分布式框架 SOFA,楼主写了一个 demo,体验了一下 SOFA 的功能,SOFA 完全兼容 SpringBoot(当然 Dubbo 也是可以兼容的). 项目地址:Alipa ...
- Java中static关键字和final关键字
static: 1. 修饰变量,方法 表示静态方法,静态变量. 2. static修饰代码块 static{ } 此种形式为静态代码块,用于初始化同时被final static修饰的变量.(当然,更常 ...
- 软工第五次作业——Python效能分析之四则运算生成器
Github项目地址: https://github.com/JtvDeemo/elementary-arithmetic PSP PSP2.1 Personal Software Process S ...