Beispiel #1
0
func FileHandler(w http.ResponseWriter, r *http.Request) {
	key := r.URL.Path

	state.addActiveDownload(1)
	defer state.addActiveDownload(-1)

	if *upstream == "" { // Master
		if slaveAddr, err := slaveMap.PeekSlave(); err == nil {
			u, _ := url.Parse(slaveAddr)
			u.Path = r.URL.Path
			u.RawQuery = r.URL.RawQuery
			http.Redirect(w, r, u.String(), 302)
			return
		}
	}
	fmt.Println("KEY:", key)
	var data []byte
	var ctx groupcache.Context
	err := thumbNails.Get(ctx, key, groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	var modTime time.Time = time.Now()

	rd := bytes.NewReader(data)
	http.ServeContent(w, r, filepath.Base(key), modTime, rd)
}
Beispiel #2
0
func FileHandler(w http.ResponseWriter, r *http.Request) {
	key := r.URL.Path

	state.addActiveDownload(1)
	defer state.addActiveDownload(-1)

	if *upstream == "" { // Master
		if peerAddr, err := peerGroup.PeekPeer(); err == nil {
			u, _ := url.Parse(peerAddr)
			u.Path = r.URL.Path
			u.RawQuery = r.URL.RawQuery
			http.Redirect(w, r, u.String(), 302)
			return
		}
	}
	//fmt.Println("KEY:", key)
	var data []byte
	var ctx groupcache.Context
	err := thumbNails.Get(ctx, key, groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	sendc <- map[string]interface{}{
		"remote_addr": r.RemoteAddr,
		"key":         key,
		"success":     err == nil,
	}
	var modTime time.Time = time.Now()

	rd := bytes.NewReader(data)
	http.ServeContent(w, r, filepath.Base(key), modTime, rd)
}
Beispiel #3
0
func FileHandler(w http.ResponseWriter, r *http.Request) {
	key := r.URL.Path

	state.addActiveDownload(1)
	defer state.addActiveDownload(-1)

	if *upstream == "" { // Master
		if peerAddr, err := peerGroup.PeekPeer(); err == nil {
			u, _ := url.Parse(peerAddr)
			u.Path = r.URL.Path
			u.RawQuery = r.URL.RawQuery
			http.Redirect(w, r, u.String(), 302)
			return
		}
	}
	//fmt.Println("KEY:", key)
	var data []byte
	var ctx groupcache.Context
	err := thumbNails.Get(ctx, key, groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	sendData := map[string]interface{}{
		"remote_addr": r.RemoteAddr,
		"key":         key,
		"success":     err == nil,
		"user_agent":  r.Header.Get("User-Agent"),
	}
	headerData := r.Header.Get("X-Minicdn-Data")
	headerType := r.Header.Get("X-Minicdn-Type")
	if headerType == "json" {
		var data interface{}
		if err := json.Unmarshal([]byte(headerData), &data); err == nil {
			sendData["header_data"] = data
		}
	} else {
		sendData["header_data"] = headerData
		sendData["header_type"] = headerType
	}

	sendc <- sendData
	var modTime time.Time = time.Now()

	rd := bytes.NewReader(data)
	http.ServeContent(w, r, filepath.Base(key), modTime, rd)
}
Beispiel #4
0
func FileHandler(w http.ResponseWriter, r *http.Request) {
	key := r.URL.Path

	state.addActiveDownload(1)
	defer state.addActiveDownload(-1)

	sendStats(r) // stats send to master

	if *upstream == "" { // Master
		if peerAddr, err := peerGroup.PeekPeer(); err == nil {
			u, _ := url.Parse(peerAddr)
			u.Path = r.URL.Path
			u.RawQuery = r.URL.RawQuery
			http.Redirect(w, r, u.String(), 302)
			return
		}
	}

	var err error
	var hr HttpResponse
	var rd io.ReadSeeker
	var data []byte
	var ctx groupcache.Context

	// Read Local File
	if err = hr.LoadMeta(key); err == nil {
		fmt.Printf("load local file: %s\n", key)
		bodyfd, er := os.Open(hr.bodyPath)
		if er != nil {
			http.Error(w, er.Error(), 500)
			return
		}
		rd = bodyfd
		goto SERVE_CONTENT
	}

	// Read Groupcache
	err = thumbNails.Get(ctx, key, groupcache.AllocatingByteSliceSink(&data))
	if err == nil {
		// FIXME(ssx): use gob is not a good way.
		// It will create new space for hr.BodyData which will use too much memory.
		if err = GobDecode(data, &hr); err != nil {
			http.Error(w, err.Error(), 500)
			return
		}
		rd = bytes.NewReader(hr.BodyData)
		fmt.Printf("groupcache: %s, len(data): %d, addr: %p\n", key, len(data), &data[0])
		goto SERVE_CONTENT
	}
	// Too big file will not use groupcache memory storage
	if es, ok := err.(*ErrorWithResponse); ok {
		switch es.Type {
		case ER_TYPE_FILE: // Read local file again
			if er := hr.LoadMeta(key); er != nil {
				http.Error(w, er.Error(), 500)
				return
			}
			bodyfd, er := os.Open(hr.bodyPath)
			if er != nil {
				http.Error(w, er.Error(), 500)
				return
			}
			defer bodyfd.Close()
			rd = bodyfd
			goto SERVE_CONTENT
		case ER_TYPE_HTML:
			w.WriteHeader(es.Resp.StatusCode)
			for name, _ := range hr.Header {
				w.Header().Set(name, es.Resp.Header.Get(key))
			}
			w.Write(es.Resp.BodyData)
			return
		default:
			log.Println("unknown es.Type:", es.Type)
		}
	}
	// Handle groupcache error
	http.Error(w, err.Error(), 500)
	return

SERVE_CONTENT:
	// FIXME(ssx): should have some better way to set header
	// header and modTime
	for key, _ := range hr.Header {
		w.Header().Set(key, hr.Header.Get(key))
	}
	modTime, err := time.Parse(http.TimeFormat, hr.Header.Get("Last-Modified"))
	if err != nil {
		modTime = time.Now()
	}
	http.ServeContent(w, r, filepath.Base(key), modTime, rd)
}
Beispiel #5
0
func FileHandler(w http.ResponseWriter, r *http.Request) {
	key := r.URL.Path

	state.addActiveDownload(1)
	defer state.addActiveDownload(-1)

	if *upstream == "" { // Master
		if peerAddr, err := peerGroup.PeekPeer(); err == nil {
			u, _ := url.Parse(peerAddr)
			u.Path = r.URL.Path
			u.RawQuery = r.URL.RawQuery
			http.Redirect(w, r, u.String(), 302)
			return
		}
	}
	fmt.Println("KEY:", key)
	var data []byte
	var ctx groupcache.Context
	err := thumbNails.Get(ctx, key, groupcache.AllocatingByteSliceSink(&data))
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	var hr HttpResponse
	mpdec := codec.NewDecoder(bytes.NewReader(data), &codec.MsgpackHandle{})
	err = mpdec.Decode(&hr)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
	// FIXME(ssx): should have some better way
	for key, _ := range hr.Header {
		w.Header().Set(key, hr.Header.Get(key))
	}

	sendData := map[string]interface{}{
		"remote_addr": r.RemoteAddr,
		"key":         key,
		"success":     err == nil,
		"user_agent":  r.Header.Get("User-Agent"),
	}
	headerData := r.Header.Get("X-Minicdn-Data")
	headerType := r.Header.Get("X-Minicdn-Type")
	if headerType == "json" {
		var data interface{}
		err := json.Unmarshal([]byte(headerData), &data)
		if err == nil {
			sendData["header_data"] = data
			sendData["header_type"] = headerType
		} else {
			log.Println("header data decode:", err)
		}
	} else {
		sendData["header_data"] = headerData
		sendData["header_type"] = headerType
	}

	if *upstream != "" { // Slave
		sendc <- sendData
	}
	// FIXME(ssx): ModTime should from header
	var modTime time.Time = time.Now()

	rd := bytes.NewReader(hr.Body)
	http.ServeContent(w, r, filepath.Base(key), modTime, rd)
}