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) }
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) }
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) }
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) }
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) }