惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
腾讯CDC
T
Threatpost
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
Cisco Talos Blog
Cisco Talos Blog
C
Cisco Blogs
A
Arctic Wolf
人人都是产品经理
人人都是产品经理
NISL@THU
NISL@THU
L
LINUX DO - 热门话题
爱范儿
爱范儿
GbyAI
GbyAI
The Register - Security
The Register - Security
AWS News Blog
AWS News Blog
MyScale Blog
MyScale Blog
T
Tenable Blog
Hugging Face - Blog
Hugging Face - Blog
A
About on SuperTechFans
Cyberwarzone
Cyberwarzone
量子位
Microsoft Azure Blog
Microsoft Azure Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
C
Cybersecurity and Infrastructure Security Agency CISA
The Cloudflare Blog
B
Blog RSS Feed
小众软件
小众软件
D
Docker
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta
Latest news
Latest news
AI
AI
SecWiki News
SecWiki News
酷 壳 – CoolShell
酷 壳 – CoolShell
S
Secure Thoughts
N
News | PayPal Newsroom
The Hacker News
The Hacker News
MongoDB | Blog
MongoDB | Blog
Martin Fowler
Martin Fowler
博客园 - 司徒正美
L
Lohrmann on Cybersecurity
Cloudbric
Cloudbric

博客园 - 强悍的抽屉

基于 Dapper 的一个 DbUtils WebAPI 操作返回 c#版 mqtt 3.1.1 client 实现 mqtt 协议之 PINGREQ, PINGRESP httpWebRequest 文件下载 MongoDB 刷新几次就报错 C# Win32API - 强悍的抽屉 - 博客园 回车跳转控件焦点 让程序只启动一次 -- Mutex C# 排序 WINDEF.h 变量类型 SqlHelper 数据库操作类2 SqlHelper 数据库操作类 第一个 Windows 应用程序 JavaScript 字符串处理函数 - 强悍的抽屉 - 博客园 JavaScript 字符串函数扩充 - 强悍的抽屉 - 博客园 C# 字符串处理一些方法 希望找人一起写个 Ajax 的封装 几种流行的JS框架的选择
一个 go 文件服务器 ssdb
强悍的抽屉 · 2015-07-28 · via 博客园 - 强悍的抽屉

file system ssdb

go http listen

文件存储到 ssdb

gfs 

|

twemproxy

|

ssdb(master) ssdb(slave)

ssdb 连接协议为 redis 协议

生成MD5 KEY

 handle.go 代码

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"path"
)

func (ctx *Context) server(w http.ResponseWriter, r *http.Request) {
	//params := r.URL.Query()
	//key := params.Get("k")
	//callback := params.Get("cb")
	path := r.URL.Path

	if path == "/" {
		home(w, r)
	} else {
		md5key := path[1:len(path)]
		fmt.Println("md5key:" + md5key)

		ctx.store.Get("key")

		val, err := ctx.store.Get(md5key)
		if err != nil {
			fmt.Fprint(w, "the file not exits!")
		}

		fmt.Fprint(w, val)
		ctx.download(w, r, md5key)
	}
}

func home(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "Method Not Allowed", 405)
		return
	}

	html := `<!DOCTYPE html>
	<html>
	    <head>
	        <meta charset="UTF-8"/>
	    </head>
	    <body>
	        <form action="/upload" method="POST" enctype="multipart/form-data">
	            <label for="field1">file:</label>
	            <input name="file" type="file" />
	            <input type="submit"></input>
	        </form>
	    </body>
	</html>`

	fmt.Fprint(w, html)
}

func (ctx *Context) upload(w http.ResponseWriter, r *http.Request) {
	//	if err := r.ParseMultipartForm(CACHE_MAX_SIZE); err != nil {
	//		//ctx.context.Logger.Error(err.Error())
	//		//ctx.doError(err, http.StatusForbidden)
	//		return
	//	}

	file, handle, err := r.FormFile("file")
	if err != nil {
		//ctx.doError(err, 500)
		fmt.Println(err)
		return
	}
	defer file.Close()

	//fmt.Println("upload file:%s", handle.Filename)
	//fmt.Println("ext" + path.Ext(handle.Filename))
	ext := path.Ext(handle.Filename)

	data, err := ioutil.ReadAll(file)
	if err != nil {
		//ctx.doError(err, 500)
		fmt.Println(err)
		return
	}

	md5key := fmt.Sprintf("%s%s", gen_md5_str(data), ext)

	ctx.store.Set(md5key, data)
	if err != nil {
		//fmt.Println("upload file fail:" md5key)
		fmt.Println(err)
		return
	}
	w.Write([]byte(fmt.Sprintf("%s", md5key)))
}

func (ctx *Context) download(w http.ResponseWriter, r *http.Request, key string) {
	val, err := ctx.store.Get(key)
	if err != nil {
		fmt.Fprint(w, "the file not exits!")
	}
	fmt.Fprint(w, val)
}

代码托管到 github

https://github.com/dtxlink/gfs