github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/api/host.go (about)

     1  package api
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/NebulousLabs/Sia/crypto"
     9  	"github.com/NebulousLabs/Sia/modules"
    10  
    11  	"github.com/julienschmidt/httprouter"
    12  )
    13  
    14  var (
    15  	// errStorageFolderNotFound is returned if a call is made looking for a
    16  	// storage folder which does not appear to exist within the storage
    17  	// manager.
    18  	errStorageFolderNotFound = errors.New("storage folder with the provided path could not be found")
    19  )
    20  
    21  type (
    22  	// HostGET contains the information that is returned after a GET request to
    23  	// /host - a bunch of information about the status of the host.
    24  	HostGET struct {
    25  		ExternalSettings modules.HostExternalSettings `json:"externalsettings"`
    26  		FinancialMetrics modules.HostFinancialMetrics `json:"financialmetrics"`
    27  		InternalSettings modules.HostInternalSettings `json:"internalsettings"`
    28  		NetworkMetrics   modules.HostNetworkMetrics   `json:"networkmetrics"`
    29  	}
    30  
    31  	// StorageGET contains the information that is returned after a GET request
    32  	// to /storage - a bunch of information about the status of storage
    33  	// management on the host.
    34  	StorageGET struct {
    35  		StorageFolderMetadata []modules.StorageFolderMetadata
    36  	}
    37  )
    38  
    39  // folderIndex determines the index of the storage folder with the provided
    40  // path.
    41  func folderIndex(folderPath string, storageFolders []modules.StorageFolderMetadata) (int, error) {
    42  	for i, sf := range storageFolders {
    43  		if sf.Path == folderPath {
    44  			return i, nil
    45  		}
    46  	}
    47  	return -1, errStorageFolderNotFound
    48  }
    49  
    50  // hostHandlerGET handles GET requests to the /host API endpoint, returning key
    51  // information about the host.
    52  func (srv *Server) hostHandlerGET(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
    53  	es := srv.host.ExternalSettings()
    54  	fm := srv.host.FinancialMetrics()
    55  	is := srv.host.InternalSettings()
    56  	nm := srv.host.NetworkMetrics()
    57  	hg := HostGET{
    58  		ExternalSettings: es,
    59  		FinancialMetrics: fm,
    60  		InternalSettings: is,
    61  		NetworkMetrics:   nm,
    62  	}
    63  	writeJSON(w, hg)
    64  }
    65  
    66  // hostHandlerPOST handles POST request to the /host API endpoint, which sets
    67  // the internal settings of the host.
    68  func (srv *Server) hostHandlerPOST(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
    69  	// Map each query string to a field in the host settings.
    70  	settings := srv.host.InternalSettings()
    71  	qsVars := map[string]interface{}{
    72  		"acceptingcontracts":   &settings.AcceptingContracts,
    73  		"maxduration":          &settings.MaxDuration,
    74  		"maxdownloadbatchsize": &settings.MaxDownloadBatchSize,
    75  		"maxrevisebatchsize":   &settings.MaxReviseBatchSize,
    76  		"netaddress":           &settings.NetAddress,
    77  		"windowsize":           &settings.WindowSize,
    78  
    79  		"collateral":       &settings.Collateral,
    80  		"collateralbudget": &settings.CollateralBudget,
    81  		"maxcollateral":    &settings.MaxCollateral,
    82  
    83  		"downloadlimitgrowth": &settings.DownloadLimitGrowth,
    84  		"downloadlimitcap":    &settings.DownloadLimitCap,
    85  		"downloadspeedlimit":  &settings.DownloadSpeedLimit,
    86  		"uploadlimitgrowth":   &settings.UploadLimitGrowth,
    87  		"uploadlimitcap":      &settings.UploadLimitCap,
    88  		"uploadspeedlimit":    &settings.UploadSpeedLimit,
    89  
    90  		"minimumcontractprice":          &settings.MinimumContractPrice,
    91  		"minimumdownloadbandwidthprice": &settings.MinimumDownloadBandwidthPrice,
    92  		"minimumstorageprice":           &settings.MinimumStoragePrice,
    93  		"minimumuploadbandwidthprice":   &settings.MinimumUploadBandwidthPrice,
    94  	}
    95  
    96  	// Iterate through the query string and replace any fields that have been
    97  	// altered.
    98  	for qs := range qsVars {
    99  		if req.FormValue(qs) != "" { // skip empty values
   100  			_, err := fmt.Sscan(req.FormValue(qs), qsVars[qs])
   101  			if err != nil {
   102  				writeError(w, "Malformed "+qs, http.StatusBadRequest)
   103  				return
   104  			}
   105  		}
   106  	}
   107  	err := srv.host.SetInternalSettings(settings)
   108  	if err != nil {
   109  		writeError(w, err.Error(), http.StatusBadRequest)
   110  		return
   111  	}
   112  	writeSuccess(w)
   113  }
   114  
   115  // hostAnnounceHandler handles the API call to get the host to announce itself
   116  // to the network.
   117  func (srv *Server) hostAnnounceHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
   118  	var err error
   119  	if addr := req.FormValue("netaddress"); addr != "" {
   120  		err = srv.host.AnnounceAddress(modules.NetAddress(addr))
   121  	} else {
   122  		err = srv.host.Announce()
   123  	}
   124  	if err != nil {
   125  		writeError(w, err.Error(), http.StatusBadRequest)
   126  		return
   127  	}
   128  	writeSuccess(w)
   129  }
   130  
   131  // storageHandler returns a bunch of information about storage management on
   132  // the host.
   133  func (srv *Server) storageHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
   134  	sfs := srv.host.StorageFolders()
   135  	sg := StorageGET{
   136  		StorageFolderMetadata: sfs,
   137  	}
   138  	writeJSON(w, sg)
   139  }
   140  
   141  // storageFoldersAddHandler adds a storage folder to the storage manager.
   142  func (srv *Server) storageFoldersAddHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
   143  	folderPath := req.FormValue("path")
   144  	var folderSize uint64
   145  	_, err := fmt.Sscan(req.FormValue("size"), &folderSize)
   146  	if err != nil {
   147  		writeError(w, err.Error(), http.StatusBadRequest)
   148  		return
   149  	}
   150  	err = srv.host.AddStorageFolder(folderPath, folderSize)
   151  	if err != nil {
   152  		writeError(w, err.Error(), http.StatusBadRequest)
   153  		return
   154  	}
   155  	writeSuccess(w)
   156  }
   157  
   158  // storageFoldersResizeHandler resizes a storage folder in the storage manager.
   159  func (srv *Server) storageFoldersResizeHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
   160  	folderPath := req.FormValue("path")
   161  	storageFolders := srv.host.StorageFolders()
   162  	folderIndex, err := folderIndex(folderPath, storageFolders)
   163  	if err != nil {
   164  		writeError(w, err.Error(), http.StatusBadRequest)
   165  		return
   166  	}
   167  
   168  	var newSize uint64
   169  	_, err = fmt.Sscan(req.FormValue("newsize"), &newSize)
   170  	if err != nil {
   171  		writeError(w, err.Error(), http.StatusBadRequest)
   172  		return
   173  	}
   174  	err = srv.host.ResizeStorageFolder(folderIndex, newSize)
   175  	if err != nil {
   176  		writeError(w, err.Error(), http.StatusBadRequest)
   177  		return
   178  	}
   179  	writeSuccess(w)
   180  }
   181  
   182  // storageFoldersRemoveHandler removes a storage folder from the storage
   183  // manager.
   184  func (srv *Server) storageFoldersRemoveHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
   185  	folderPath := req.FormValue("path")
   186  	storageFolders := srv.host.StorageFolders()
   187  	folderIndex, err := folderIndex(folderPath, storageFolders)
   188  	if err != nil {
   189  		writeError(w, err.Error(), http.StatusBadRequest)
   190  		return
   191  	}
   192  
   193  	force := req.FormValue("force") == "true"
   194  	err = srv.host.RemoveStorageFolder(folderIndex, force)
   195  	if err != nil {
   196  		writeError(w, err.Error(), http.StatusBadRequest)
   197  		return
   198  	}
   199  	writeSuccess(w)
   200  }
   201  
   202  // storageSectorsDeleteHandler handles the call to delete a sector from the
   203  // storage manager.
   204  func (srv *Server) storageSectorsDeleteHandler(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
   205  	sectorRoot, err := scanAddress(ps.ByName("merkleroot"))
   206  	if err != nil {
   207  		writeError(w, err.Error(), http.StatusBadRequest)
   208  		return
   209  	}
   210  	err = srv.host.DeleteSector(crypto.Hash(sectorRoot))
   211  	if err != nil {
   212  		writeError(w, err.Error(), http.StatusBadRequest)
   213  		return
   214  	}
   215  	writeSuccess(w)
   216  }