github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/api/api.go (about) 1 package api 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "strings" 7 8 "github.com/julienschmidt/httprouter" 9 ) 10 11 // HttpGET is a utility function for making http get requests to sia with a whitelisted user-agent 12 func HttpGET(url string) (resp *http.Response, err error) { 13 req, err := http.NewRequest("GET", url, nil) 14 if err != nil { 15 return nil, err 16 } 17 req.Header.Add("User-Agent", "Sia-Agent") 18 return new(http.Client).Do(req) 19 } 20 21 // HttpPOST is a utility function for making post requests to sia with a whitelisted user-agent 22 func HttpPOST(url string, data string) (resp *http.Response, err error) { 23 req, err := http.NewRequest("POST", url, strings.NewReader(data)) 24 if err != nil { 25 return nil, err 26 } 27 req.Header.Add("User-Agent", "Sia-Agent") 28 req.Header.Add("Content-Type", "application/x-www-form-urlencoded") 29 return new(http.Client).Do(req) 30 } 31 32 // requireUserAgent is middleware that requires all requests to set a 33 // UserAgent that contains the specified string. 34 func requireUserAgent(h http.Handler, ua string) http.Handler { 35 return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 36 if !strings.Contains(req.UserAgent(), ua) { 37 writeError(w, "Browser access disabled due to security vulnerability. Use Sia-UI or siac.", http.StatusBadRequest) 38 return 39 } 40 h.ServeHTTP(w, req) 41 }) 42 } 43 44 // initAPI determines which functions handle each API call. 45 func (srv *Server) initAPI() { 46 router := httprouter.New() 47 router.NotFound = http.HandlerFunc(srv.unrecognizedCallHandler) // custom 404 48 49 // Daemon API Calls 50 router.GET("/daemon/constants", srv.daemonConstantsHandler) 51 router.GET("/daemon/version", srv.daemonVersionHandler) 52 router.GET("/daemon/stop", srv.daemonStopHandler) 53 54 // Consensus API Calls 55 if srv.cs != nil { 56 router.GET("/consensus", srv.consensusHandler) 57 } 58 59 // Explorer API Calls 60 if srv.explorer != nil { 61 router.GET("/explorer", srv.explorerHandler) 62 router.GET("/explorer/blocks/:height", srv.explorerBlocksHandler) 63 router.GET("/explorer/hashes/:hash", srv.explorerHashHandler) 64 } 65 66 // Gateway API Calls 67 if srv.gateway != nil { 68 router.GET("/gateway", srv.gatewayHandler) 69 router.POST("/gateway/add/:netaddress", srv.gatewayAddHandler) 70 router.POST("/gateway/remove/:netaddress", srv.gatewayRemoveHandler) 71 } 72 73 // Host API Calls 74 if srv.host != nil { 75 // Calls directly pertaining to the host. 76 router.GET("/host", srv.hostHandlerGET) // Get a bunch of information about the host. 77 router.POST("/host", srv.hostHandlerPOST) // Set HostInternalSettings. 78 router.POST("/host/announce", srv.hostAnnounceHandler) // Announce the host, optionally on a specific address. 79 80 // Calls pertaining to the storage manager that the host uses. 81 router.GET("/storage", srv.storageHandler) 82 router.POST("/storage/folders/add", srv.storageFoldersAddHandler) 83 router.POST("/storage/folders/remove", srv.storageFoldersRemoveHandler) 84 router.POST("/storage/folders/resize", srv.storageFoldersResizeHandler) 85 router.POST("/storage/sectors/delete/:merkleroot", srv.storageSectorsDeleteHandler) 86 } 87 88 // Miner API Calls 89 if srv.miner != nil { 90 router.GET("/miner", srv.minerHandler) 91 router.GET("/miner/header", srv.minerHeaderHandlerGET) 92 router.POST("/miner/header", srv.minerHeaderHandlerPOST) 93 router.GET("/miner/start", srv.minerStartHandler) 94 router.GET("/miner/stop", srv.minerStopHandler) 95 router.GET("/miner/headerforwork", srv.minerHeaderHandlerGET) // COMPATv0.4.8 96 router.POST("/miner/submitheader", srv.minerHeaderHandlerPOST) // COMPATv0.4.8 97 } 98 99 // Renter API Calls 100 if srv.renter != nil { 101 router.GET("/renter", srv.renterHandler) 102 router.GET("/renter/allowance", srv.renterAllowanceHandlerGET) 103 router.POST("/renter/allowance", srv.renterAllowanceHandlerPOST) 104 router.GET("/renter/contracts", srv.renterContractsHandler) 105 router.GET("/renter/downloads", srv.renterDownloadsHandler) 106 router.GET("/renter/files", srv.renterFilesHandler) 107 108 router.POST("/renter/load", srv.renterLoadHandler) 109 router.POST("/renter/loadascii", srv.renterLoadAsciiHandler) 110 router.GET("/renter/share", srv.renterShareHandler) 111 router.GET("/renter/shareascii", srv.renterShareAsciiHandler) 112 113 router.POST("/renter/delete/*siapath", srv.renterDeleteHandler) 114 router.GET("/renter/download/*siapath", srv.renterDownloadHandler) 115 router.POST("/renter/rename/*siapath", srv.renterRenameHandler) 116 router.POST("/renter/upload/*siapath", srv.renterUploadHandler) 117 118 router.GET("/renter/hosts/active", srv.renterHostsActiveHandler) 119 router.GET("/renter/hosts/all", srv.renterHostsAllHandler) 120 } 121 122 // TransactionPool API Calls 123 if srv.tpool != nil { 124 router.GET("/transactionpool/transactions", srv.transactionpoolTransactionsHandler) 125 } 126 127 // Wallet API Calls 128 if srv.wallet != nil { 129 router.GET("/wallet", srv.walletHandler) 130 router.POST("/wallet/033x", srv.wallet033xHandler) 131 router.GET("/wallet/address", srv.walletAddressHandler) 132 router.GET("/wallet/addresses", srv.walletAddressesHandler) 133 router.GET("/wallet/backup", srv.walletBackupHandler) 134 router.POST("/wallet/init", srv.walletInitHandler) 135 router.POST("/wallet/lock", srv.walletLockHandler) 136 router.POST("/wallet/seed", srv.walletSeedHandler) 137 router.GET("/wallet/seeds", srv.walletSeedsHandler) 138 router.POST("/wallet/siacoins", srv.walletSiacoinsHandler) 139 router.POST("/wallet/siafunds", srv.walletSiafundsHandler) 140 router.POST("/wallet/siagkey", srv.walletSiagkeyHandler) 141 router.GET("/wallet/transaction/:id", srv.walletTransactionHandler) 142 router.GET("/wallet/transactions", srv.walletTransactionsHandler) 143 router.GET("/wallet/transactions/:addr", srv.walletTransactionsAddrHandler) 144 router.POST("/wallet/unlock", srv.walletUnlockHandler) 145 router.POST("/wallet/encrypt", srv.walletInitHandler) // COMPATv0.4.0 146 } 147 148 // Apply UserAgent middleware and create HTTP server 149 uaRouter := requireUserAgent(router, srv.requiredUserAgent) 150 srv.apiServer = &http.Server{Handler: uaRouter} 151 } 152 153 // unrecognizedCallHandler handles calls to unknown pages (404). 154 func (srv *Server) unrecognizedCallHandler(w http.ResponseWriter, req *http.Request) { 155 http.Error(w, "404 - Refer to API.md", http.StatusNotFound) 156 } 157 158 // writeError an error to the API caller. 159 func writeError(w http.ResponseWriter, msg string, err int) { 160 http.Error(w, msg, err) 161 } 162 163 // writeJSON writes the object to the ResponseWriter. If the encoding fails, an 164 // error is written instead. 165 func writeJSON(w http.ResponseWriter, obj interface{}) { 166 if json.NewEncoder(w).Encode(obj) != nil { 167 http.Error(w, "Failed to encode response", http.StatusInternalServerError) 168 } 169 } 170 171 // writeSuccess writes the success json object ({"Success":true}) to the 172 // ResponseWriter 173 func writeSuccess(w http.ResponseWriter) { 174 writeJSON(w, struct{ Success bool }{true}) 175 }