Exemplo n.º 1
0
Arquivo: param.go Projeto: frazy/babou
// Applies the context to a ParamterizedController
func (dc *DevContext) ApplyContext(controller web.Controller, response http.ResponseWriter, request *http.Request, chain []web.ChainableContext) {
	dc.SetParams(web.RetrieveAllParams(request))
	dc.SetResponsePair(response, request)

	dc.isInit = true

	v, ok := controller.(ParameterizedController)
	if ok {
		if err := v.SetContext(dc); err != nil {
			fmt.Printf("Error setting paramter context: %s \n", err.Error())
		}
	} else {
		fmt.Printf("Tried to wrap a controller that is not request parameter aware \n")
	}
}
Exemplo n.º 2
0
// Handles announce from a client.
// Some TODOs:
//  * Bail out early if secret/hash or request is obviously malformed. (Not from a well-behaved torrent client.)
//  * Cache users and their secrets. (Presumably if they have started one torrent they will start many more.)
//  * Intelligent peer-list generation.
//  * Set `Content-Length` ?
func announceHandle(w http.ResponseWriter, r *http.Request, s *Server) {
	w.Header().Set("Content-Type", "text/plain")

	params := libWeb.RetrieveAllParams(r)
	responseMap := make(map[string]interface{})

	hexHash := hex.EncodeToString([]byte(params.All["info_hash"]))

	torrent, ok := s.torrentExists(hexHash)

	user := &models.User{}
	if err := user.SelectSecret(params.All["secret"]); err != nil {
		w.Write(failureResponses[RESP_USER_NOT_FOUND])

		return
	}

	if !libTorrent.CheckHmac(params.All["secret"], params.All["hash"]) {
		w.Write(failureResponses[RESP_USER_NOT_FOUND])

		return
	}

	// TODO: tracker request log.

	if !ok {
		w.Write(failureResponses[RESP_TORRENT_NOT_FOUND])
		return
	}

	responseMap["interval"] = lib.TRACKER_ANNOUNCE_INTERVAL // intentionally short for debugging purposes.
	responseMap["min interval"] = 10

	seeding, leeching := torrent.EnumeratePeers()
	responseMap["complete"] = seeding
	responseMap["incomplete"] = leeching

	responseMap["peers"], responseMap["peers6"] = torrent.GetPeerList(0) //naive peer ranker.
	io.Copy(w, encodeResponseMap(responseMap))

	// Defer writes outside of response
	// (Just in case we block on DB access or have to contend for the peer list's mutex)
	go func() {
		if params.All["event"] == "stopped" {
			// TODO: remove peer method
			torrent.WritePeers(func(peerMap map[string]*libTorrent.Peer) {
				delete(peerMap, params.All["peer_id"])
			})
		} else {
			torrent.AddPeer(
				params.All["peer_id"],
				r.RemoteAddr,
				params.All["port"],
				params.All["secret"],
			)

			torrent.UpdateStatsFor(params.All["peer_id"], "0", "0", params.All["left"])
		}

		// Send stats over event bridge.
		stats := libBridge.TorrentStatMessage{}
		stats.InfoHash = torrent.InfoHash
		stats.Seeding, stats.Leeching = torrent.EnumeratePeers()

		message := &libBridge.Message{}
		message.Type = libBridge.TORRENT_STAT_TUPLE
		message.Payload = stats

		// TODO: Reaper needs to send this event
		// when a peer is removed.

		s.eventBridge.Publish("tracker", message)

	}()
}