github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/aria2/rpc/client.go (about)

     1  package rpc
     2  
     3  import (
     4  	"context"
     5  	"encoding/base64"
     6  	"errors"
     7  	"io/ioutil"
     8  	"net/url"
     9  	"time"
    10  )
    11  
    12  // Option is a container for specifying Call parameters and returning results
    13  type Option map[string]interface{}
    14  
    15  type Client interface {
    16  	Protocol
    17  	Close() error
    18  }
    19  
    20  type client struct {
    21  	caller
    22  	url   *url.URL
    23  	token string
    24  }
    25  
    26  var (
    27  	errInvalidParameter = errors.New("invalid parameter")
    28  	errNotImplemented   = errors.New("not implemented")
    29  	errConnTimeout      = errors.New("connect to aria2 daemon timeout")
    30  )
    31  
    32  // New returns an instance of Client
    33  func New(ctx context.Context, uri string, token string, timeout time.Duration, notifier Notifier) (Client, error) {
    34  	u, err := url.Parse(uri)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	var caller caller
    39  	switch u.Scheme {
    40  	case "http", "https":
    41  		caller = newHTTPCaller(ctx, u, timeout, notifier)
    42  	case "ws", "wss":
    43  		caller, err = newWebsocketCaller(ctx, u.String(), timeout, notifier)
    44  		if err != nil {
    45  			return nil, err
    46  		}
    47  	default:
    48  		return nil, errInvalidParameter
    49  	}
    50  	c := &client{caller: caller, url: u, token: token}
    51  	return c, nil
    52  }
    53  
    54  // `aria2.addUri([secret, ]uris[, options[, position]])`
    55  // This method adds a new download. uris is an array of HTTP/FTP/SFTP/BitTorrent URIs (strings) pointing to the same resource.
    56  // If you mix URIs pointing to different resources, then the download may fail or be corrupted without aria2 complaining.
    57  // When adding BitTorrent Magnet URIs, uris must have only one element and it should be BitTorrent Magnet URI.
    58  // options is a struct and its members are pairs of option name and value.
    59  // If position is given, it must be an integer starting from 0.
    60  // The new download will be inserted at position in the waiting queue.
    61  // If position is omitted or position is larger than the current size of the queue, the new download is appended to the end of the queue.
    62  // This method returns the GID of the newly registered download.
    63  func (c *client) AddURI(uri string, options ...interface{}) (gid string, err error) {
    64  	params := make([]interface{}, 0, 2)
    65  	if c.token != "" {
    66  		params = append(params, "token:"+c.token)
    67  	}
    68  	params = append(params, []string{uri})
    69  	if options != nil {
    70  		params = append(params, options...)
    71  	}
    72  	err = c.Call(aria2AddURI, params, &gid)
    73  	return
    74  }
    75  
    76  // `aria2.addTorrent([secret, ]torrent[, uris[, options[, position]]])`
    77  // This method adds a BitTorrent download by uploading a ".torrent" file.
    78  // If you want to add a BitTorrent Magnet URI, use the aria2.addUri() method instead.
    79  // torrent must be a base64-encoded string containing the contents of the ".torrent" file.
    80  // uris is an array of URIs (string). uris is used for Web-seeding.
    81  // For single file torrents, the URI can be a complete URI pointing to the resource; if URI ends with /, name in torrent file is added.
    82  // For multi-file torrents, name and path in torrent are added to form a URI for each file. options is a struct and its members are pairs of option name and value.
    83  // If position is given, it must be an integer starting from 0.
    84  // The new download will be inserted at position in the waiting queue.
    85  // If position is omitted or position is larger than the current size of the queue, the new download is appended to the end of the queue.
    86  // This method returns the GID of the newly registered download.
    87  // If --rpc-save-upload-metadata is true, the uploaded data is saved as a file named as the hex string of SHA-1 hash of data plus ".torrent" in the directory specified by --dir option.
    88  // E.g. a file name might be 0a3893293e27ac0490424c06de4d09242215f0a6.torrent.
    89  // If a file with the same name already exists, it is overwritten!
    90  // If the file cannot be saved successfully or --rpc-save-upload-metadata is false, the downloads added by this method are not saved by --save-session.
    91  func (c *client) AddTorrent(filename string, options ...interface{}) (gid string, err error) {
    92  	co, err := ioutil.ReadFile(filename)
    93  	if err != nil {
    94  		return
    95  	}
    96  	file := base64.StdEncoding.EncodeToString(co)
    97  	params := make([]interface{}, 0, 2)
    98  	if c.token != "" {
    99  		params = append(params, "token:"+c.token)
   100  	}
   101  	params = append(params, file)
   102  	if options != nil {
   103  		params = append(params, options...)
   104  	}
   105  	err = c.Call(aria2AddTorrent, params, &gid)
   106  	return
   107  }
   108  
   109  // `aria2.addMetalink([secret, ]metalink[, options[, position]])`
   110  // This method adds a Metalink download by uploading a ".metalink" file.
   111  // metalink is a base64-encoded string which contains the contents of the ".metalink" file.
   112  // options is a struct and its members are pairs of option name and value.
   113  // If position is given, it must be an integer starting from 0.
   114  // The new download will be inserted at position in the waiting queue.
   115  // If position is omitted or position is larger than the current size of the queue, the new download is appended to the end of the queue.
   116  // This method returns an array of GIDs of newly registered downloads.
   117  // If --rpc-save-upload-metadata is true, the uploaded data is saved as a file named hex string of SHA-1 hash of data plus ".metalink" in the directory specified by --dir option.
   118  // E.g. a file name might be 0a3893293e27ac0490424c06de4d09242215f0a6.metalink.
   119  // If a file with the same name already exists, it is overwritten!
   120  // If the file cannot be saved successfully or --rpc-save-upload-metadata is false, the downloads added by this method are not saved by --save-session.
   121  func (c *client) AddMetalink(filename string, options ...interface{}) (gid []string, err error) {
   122  	co, err := ioutil.ReadFile(filename)
   123  	if err != nil {
   124  		return
   125  	}
   126  	file := base64.StdEncoding.EncodeToString(co)
   127  	params := make([]interface{}, 0, 2)
   128  	if c.token != "" {
   129  		params = append(params, "token:"+c.token)
   130  	}
   131  	params = append(params, file)
   132  	if options != nil {
   133  		params = append(params, options...)
   134  	}
   135  	err = c.Call(aria2AddMetalink, params, &gid)
   136  	return
   137  }
   138  
   139  // `aria2.remove([secret, ]gid)`
   140  // This method removes the download denoted by gid (string).
   141  // If the specified download is in progress, it is first stopped.
   142  // The status of the removed download becomes removed.
   143  // This method returns GID of removed download.
   144  func (c *client) Remove(gid string) (g string, err error) {
   145  	params := make([]interface{}, 0, 2)
   146  	if c.token != "" {
   147  		params = append(params, "token:"+c.token)
   148  	}
   149  	params = append(params, gid)
   150  	err = c.Call(aria2Remove, params, &g)
   151  	return
   152  }
   153  
   154  // `aria2.forceRemove([secret, ]gid)`
   155  // This method removes the download denoted by gid.
   156  // This method behaves just like aria2.remove() except that this method removes the download without performing any actions which take time, such as contacting BitTorrent trackers to unregister the download first.
   157  func (c *client) ForceRemove(gid string) (g string, err error) {
   158  	params := make([]interface{}, 0, 2)
   159  	if c.token != "" {
   160  		params = append(params, "token:"+c.token)
   161  	}
   162  	params = append(params, gid)
   163  	err = c.Call(aria2ForceRemove, params, &g)
   164  	return
   165  }
   166  
   167  // `aria2.pause([secret, ]gid)`
   168  // This method pauses the download denoted by gid (string).
   169  // The status of paused download becomes paused.
   170  // If the download was active, the download is placed in the front of waiting queue.
   171  // While the status is paused, the download is not started.
   172  // To change status to waiting, use the aria2.unpause() method.
   173  // This method returns GID of paused download.
   174  func (c *client) Pause(gid string) (g string, err error) {
   175  	params := make([]interface{}, 0, 2)
   176  	if c.token != "" {
   177  		params = append(params, "token:"+c.token)
   178  	}
   179  	params = append(params, gid)
   180  	err = c.Call(aria2Pause, params, &g)
   181  	return
   182  }
   183  
   184  // `aria2.pauseAll([secret])`
   185  // This method is equal to calling aria2.pause() for every active/waiting download.
   186  // This methods returns OK.
   187  func (c *client) PauseAll() (ok string, err error) {
   188  	params := []string{}
   189  	if c.token != "" {
   190  		params = append(params, "token:"+c.token)
   191  	}
   192  	err = c.Call(aria2PauseAll, params, &ok)
   193  	return
   194  }
   195  
   196  // `aria2.forcePause([secret, ]gid)`
   197  // This method pauses the download denoted by gid.
   198  // This method behaves just like aria2.pause() except that this method pauses downloads without performing any actions which take time, such as contacting BitTorrent trackers to unregister the download first.
   199  func (c *client) ForcePause(gid string) (g string, err error) {
   200  	params := make([]interface{}, 0, 2)
   201  	if c.token != "" {
   202  		params = append(params, "token:"+c.token)
   203  	}
   204  	params = append(params, gid)
   205  	err = c.Call(aria2ForcePause, params, &g)
   206  	return
   207  }
   208  
   209  // `aria2.forcePauseAll([secret])`
   210  // This method is equal to calling aria2.forcePause() for every active/waiting download.
   211  // This methods returns OK.
   212  func (c *client) ForcePauseAll() (ok string, err error) {
   213  	params := []string{}
   214  	if c.token != "" {
   215  		params = append(params, "token:"+c.token)
   216  	}
   217  	err = c.Call(aria2ForcePauseAll, params, &ok)
   218  	return
   219  }
   220  
   221  // `aria2.unpause([secret, ]gid)`
   222  // This method changes the status of the download denoted by gid (string) from paused to waiting, making the download eligible to be restarted.
   223  // This method returns the GID of the unpaused download.
   224  func (c *client) Unpause(gid string) (g string, err error) {
   225  	params := make([]interface{}, 0, 2)
   226  	if c.token != "" {
   227  		params = append(params, "token:"+c.token)
   228  	}
   229  	params = append(params, gid)
   230  	err = c.Call(aria2Unpause, params, &g)
   231  	return
   232  }
   233  
   234  // `aria2.unpauseAll([secret])`
   235  // This method is equal to calling aria2.unpause() for every active/waiting download.
   236  // This methods returns OK.
   237  func (c *client) UnpauseAll() (ok string, err error) {
   238  	params := []string{}
   239  	if c.token != "" {
   240  		params = append(params, "token:"+c.token)
   241  	}
   242  	err = c.Call(aria2UnpauseAll, params, &ok)
   243  	return
   244  }
   245  
   246  // `aria2.tellStatus([secret, ]gid[, keys])`
   247  // This method returns the progress of the download denoted by gid (string).
   248  // keys is an array of strings.
   249  // If specified, the response contains only keys in the keys array.
   250  // If keys is empty or omitted, the response contains all keys.
   251  // This is useful when you just want specific keys and avoid unnecessary transfers.
   252  // For example, aria2.tellStatus("2089b05ecca3d829", ["gid", "status"]) returns the gid and status keys only.
   253  // The response is a struct and contains following keys. Values are strings.
   254  // https://aria2.github.io/manual/en/html/aria2c.html#aria2.tellStatus
   255  func (c *client) TellStatus(gid string, keys ...string) (info StatusInfo, err error) {
   256  	params := make([]interface{}, 0, 2)
   257  	if c.token != "" {
   258  		params = append(params, "token:"+c.token)
   259  	}
   260  	params = append(params, gid)
   261  	if keys != nil {
   262  		params = append(params, keys)
   263  	}
   264  	err = c.Call(aria2TellStatus, params, &info)
   265  	return
   266  }
   267  
   268  // `aria2.getUris([secret, ]gid)`
   269  // This method returns the URIs used in the download denoted by gid (string).
   270  // The response is an array of structs and it contains following keys. Values are string.
   271  // 	uri        URI
   272  // 	status    'used' if the URI is in use. 'waiting' if the URI is still waiting in the queue.
   273  func (c *client) GetURIs(gid string) (infos []URIInfo, err error) {
   274  	params := make([]interface{}, 0, 2)
   275  	if c.token != "" {
   276  		params = append(params, "token:"+c.token)
   277  	}
   278  	params = append(params, gid)
   279  	err = c.Call(aria2GetURIs, params, &infos)
   280  	return
   281  }
   282  
   283  // `aria2.getFiles([secret, ]gid)`
   284  // This method returns the file list of the download denoted by gid (string).
   285  // The response is an array of structs which contain following keys. Values are strings.
   286  // https://aria2.github.io/manual/en/html/aria2c.html#aria2.getFiles
   287  func (c *client) GetFiles(gid string) (infos []FileInfo, err error) {
   288  	params := make([]interface{}, 0, 2)
   289  	if c.token != "" {
   290  		params = append(params, "token:"+c.token)
   291  	}
   292  	params = append(params, gid)
   293  	err = c.Call(aria2GetFiles, params, &infos)
   294  	return
   295  }
   296  
   297  // `aria2.getPeers([secret, ]gid)`
   298  // This method returns a list peers of the download denoted by gid (string).
   299  // This method is for BitTorrent only.
   300  // The response is an array of structs and contains the following keys. Values are strings.
   301  // https://aria2.github.io/manual/en/html/aria2c.html#aria2.getPeers
   302  func (c *client) GetPeers(gid string) (infos []PeerInfo, err error) {
   303  	params := make([]interface{}, 0, 2)
   304  	if c.token != "" {
   305  		params = append(params, "token:"+c.token)
   306  	}
   307  	params = append(params, gid)
   308  	err = c.Call(aria2GetPeers, params, &infos)
   309  	return
   310  }
   311  
   312  // `aria2.getServers([secret, ]gid)`
   313  // This method returns currently connected HTTP(S)/FTP/SFTP servers of the download denoted by gid (string).
   314  // The response is an array of structs and contains the following keys. Values are strings.
   315  // https://aria2.github.io/manual/en/html/aria2c.html#aria2.getServers
   316  func (c *client) GetServers(gid string) (infos []ServerInfo, err error) {
   317  	params := make([]interface{}, 0, 2)
   318  	if c.token != "" {
   319  		params = append(params, "token:"+c.token)
   320  	}
   321  	params = append(params, gid)
   322  	err = c.Call(aria2GetServers, params, &infos)
   323  	return
   324  }
   325  
   326  // `aria2.tellActive([secret][, keys])`
   327  // This method returns a list of active downloads.
   328  // The response is an array of the same structs as returned by the aria2.tellStatus() method.
   329  // For the keys parameter, please refer to the aria2.tellStatus() method.
   330  func (c *client) TellActive(keys ...string) (infos []StatusInfo, err error) {
   331  	params := make([]interface{}, 0, 1)
   332  	if c.token != "" {
   333  		params = append(params, "token:"+c.token)
   334  	}
   335  	if keys != nil {
   336  		params = append(params, keys)
   337  	}
   338  	err = c.Call(aria2TellActive, params, &infos)
   339  	return
   340  }
   341  
   342  // `aria2.tellWaiting([secret, ]offset, num[, keys])`
   343  // This method returns a list of waiting downloads, including paused ones.
   344  // offset is an integer and specifies the offset from the download waiting at the front.
   345  // num is an integer and specifies the max. number of downloads to be returned.
   346  // For the keys parameter, please refer to the aria2.tellStatus() method.
   347  // If offset is a positive integer, this method returns downloads in the range of [offset, offset + num).
   348  // offset can be a negative integer. offset == -1 points last download in the waiting queue and offset == -2 points the download before the last download, and so on.
   349  // Downloads in the response are in reversed order then.
   350  // For example, imagine three downloads "A","B" and "C" are waiting in this order.
   351  // aria2.tellWaiting(0, 1) returns ["A"].
   352  // aria2.tellWaiting(1, 2) returns ["B", "C"].
   353  // aria2.tellWaiting(-1, 2) returns ["C", "B"].
   354  // The response is an array of the same structs as returned by aria2.tellStatus() method.
   355  func (c *client) TellWaiting(offset, num int, keys ...string) (infos []StatusInfo, err error) {
   356  	params := make([]interface{}, 0, 3)
   357  	if c.token != "" {
   358  		params = append(params, "token:"+c.token)
   359  	}
   360  	params = append(params, offset)
   361  	params = append(params, num)
   362  	if keys != nil {
   363  		params = append(params, keys)
   364  	}
   365  	err = c.Call(aria2TellWaiting, params, &infos)
   366  	return
   367  }
   368  
   369  // `aria2.tellStopped([secret, ]offset, num[, keys])`
   370  // This method returns a list of stopped downloads.
   371  // offset is an integer and specifies the offset from the least recently stopped download.
   372  // num is an integer and specifies the max. number of downloads to be returned.
   373  // For the keys parameter, please refer to the aria2.tellStatus() method.
   374  // offset and num have the same semantics as described in the aria2.tellWaiting() method.
   375  // The response is an array of the same structs as returned by the aria2.tellStatus() method.
   376  func (c *client) TellStopped(offset, num int, keys ...string) (infos []StatusInfo, err error) {
   377  	params := make([]interface{}, 0, 3)
   378  	if c.token != "" {
   379  		params = append(params, "token:"+c.token)
   380  	}
   381  	params = append(params, offset)
   382  	params = append(params, num)
   383  	if keys != nil {
   384  		params = append(params, keys)
   385  	}
   386  	err = c.Call(aria2TellStopped, params, &infos)
   387  	return
   388  }
   389  
   390  // `aria2.changePosition([secret, ]gid, pos, how)`
   391  // This method changes the position of the download denoted by gid in the queue.
   392  // pos is an integer. how is a string.
   393  // If how is POS_SET, it moves the download to a position relative to the beginning of the queue.
   394  // If how is POS_CUR, it moves the download to a position relative to the current position.
   395  // If how is POS_END, it moves the download to a position relative to the end of the queue.
   396  // If the destination position is less than 0 or beyond the end of the queue, it moves the download to the beginning or the end of the queue respectively.
   397  // The response is an integer denoting the resulting position.
   398  // For example, if GID#2089b05ecca3d829 is currently in position 3, aria2.changePosition('2089b05ecca3d829', -1, 'POS_CUR') will change its position to 2. Additionally aria2.changePosition('2089b05ecca3d829', 0, 'POS_SET') will change its position to 0 (the beginning of the queue).
   399  func (c *client) ChangePosition(gid string, pos int, how string) (p int, err error) {
   400  	params := make([]interface{}, 0, 3)
   401  	if c.token != "" {
   402  		params = append(params, "token:"+c.token)
   403  	}
   404  	params = append(params, gid)
   405  	params = append(params, pos)
   406  	params = append(params, how)
   407  	err = c.Call(aria2ChangePosition, params, &p)
   408  	return
   409  }
   410  
   411  // `aria2.changeUri([secret, ]gid, fileIndex, delUris, addUris[, position])`
   412  // This method removes the URIs in delUris from and appends the URIs in addUris to download denoted by gid.
   413  // delUris and addUris are lists of strings.
   414  // A download can contain multiple files and URIs are attached to each file.
   415  // fileIndex is used to select which file to remove/attach given URIs. fileIndex is 1-based.
   416  // position is used to specify where URIs are inserted in the existing waiting URI list. position is 0-based.
   417  // When position is omitted, URIs are appended to the back of the list.
   418  // This method first executes the removal and then the addition.
   419  // position is the position after URIs are removed, not the position when this method is called.
   420  // When removing an URI, if the same URIs exist in download, only one of them is removed for each URI in delUris.
   421  // In other words, if there are three URIs http://example.org/aria2 and you want remove them all, you have to specify (at least) 3 http://example.org/aria2 in delUris.
   422  // This method returns a list which contains two integers.
   423  // The first integer is the number of URIs deleted.
   424  // The second integer is the number of URIs added.
   425  func (c *client) ChangeURI(gid string, fileindex int, delUris []string, addUris []string, position ...int) (p []int, err error) {
   426  	params := make([]interface{}, 0, 5)
   427  	if c.token != "" {
   428  		params = append(params, "token:"+c.token)
   429  	}
   430  	params = append(params, gid)
   431  	params = append(params, fileindex)
   432  	params = append(params, delUris)
   433  	params = append(params, addUris)
   434  	if position != nil {
   435  		params = append(params, position[0])
   436  	}
   437  	err = c.Call(aria2ChangeURI, params, &p)
   438  	return
   439  }
   440  
   441  // `aria2.getOption([secret, ]gid)`
   442  // This method returns options of the download denoted by gid.
   443  // The response is a struct where keys are the names of options.
   444  // The values are strings.
   445  // Note that this method does not return options which have no default value and have not been set on the command-line, in configuration files or RPC methods.
   446  func (c *client) GetOption(gid string) (m Option, err error) {
   447  	params := make([]interface{}, 0, 2)
   448  	if c.token != "" {
   449  		params = append(params, "token:"+c.token)
   450  	}
   451  	params = append(params, gid)
   452  	err = c.Call(aria2GetOption, params, &m)
   453  	return
   454  }
   455  
   456  // `aria2.changeOption([secret, ]gid, options)`
   457  // This method changes options of the download denoted by gid (string) dynamically. options is a struct.
   458  // The following options are available for active downloads:
   459  // 	bt-max-peers
   460  // 	bt-request-peer-speed-limit
   461  // 	bt-remove-unselected-file
   462  // 	force-save
   463  // 	max-download-limit
   464  // 	max-upload-limit
   465  // For waiting or paused downloads, in addition to the above options, options listed in Input File subsection are available, except for following options: dry-run, metalink-base-uri, parameterized-uri, pause, piece-length and rpc-save-upload-metadata option.
   466  // This method returns OK for success.
   467  func (c *client) ChangeOption(gid string, option Option) (ok string, err error) {
   468  	params := make([]interface{}, 0, 2)
   469  	if c.token != "" {
   470  		params = append(params, "token:"+c.token)
   471  	}
   472  	params = append(params, gid)
   473  	if option != nil {
   474  		params = append(params, option)
   475  	}
   476  	err = c.Call(aria2ChangeOption, params, &ok)
   477  	return
   478  }
   479  
   480  // `aria2.getGlobalOption([secret])`
   481  // This method returns the global options.
   482  // The response is a struct.
   483  // Its keys are the names of options.
   484  // Values are strings.
   485  // Note that this method does not return options which have no default value and have not been set on the command-line, in configuration files or RPC methods. Because global options are used as a template for the options of newly added downloads, the response contains keys returned by the aria2.getOption() method.
   486  func (c *client) GetGlobalOption() (m Option, err error) {
   487  	params := []string{}
   488  	if c.token != "" {
   489  		params = append(params, "token:"+c.token)
   490  	}
   491  	err = c.Call(aria2GetGlobalOption, params, &m)
   492  	return
   493  }
   494  
   495  // `aria2.changeGlobalOption([secret, ]options)`
   496  // This method changes global options dynamically.
   497  // options is a struct.
   498  // The following options are available:
   499  // 	bt-max-open-files
   500  // 	download-result
   501  // 	log
   502  // 	log-level
   503  // 	max-concurrent-downloads
   504  // 	max-download-result
   505  // 	max-overall-download-limit
   506  // 	max-overall-upload-limit
   507  // 	save-cookies
   508  // 	save-session
   509  // 	server-stat-of
   510  // In addition, options listed in the Input File subsection are available, except for following options: checksum, index-out, out, pause and select-file.
   511  // With the log option, you can dynamically start logging or change log file.
   512  // To stop logging, specify an empty string("") as the parameter value.
   513  // Note that log file is always opened in append mode.
   514  // This method returns OK for success.
   515  func (c *client) ChangeGlobalOption(options Option) (ok string, err error) {
   516  	params := make([]interface{}, 0, 2)
   517  	if c.token != "" {
   518  		params = append(params, "token:"+c.token)
   519  	}
   520  	params = append(params, options)
   521  	err = c.Call(aria2ChangeGlobalOption, params, &ok)
   522  	return
   523  }
   524  
   525  // `aria2.getGlobalStat([secret])`
   526  // This method returns global statistics such as the overall download and upload speeds.
   527  // The response is a struct and contains the following keys. Values are strings.
   528  // 	downloadSpeed      Overall download speed (byte/sec).
   529  // 	uploadSpeed        Overall upload speed(byte/sec).
   530  // 	numActive          The number of active downloads.
   531  // 	numWaiting         The number of waiting downloads.
   532  // 	numStopped         The number of stopped downloads in the current session.
   533  //                     This value is capped by the --max-download-result option.
   534  // 	numStoppedTotal    The number of stopped downloads in the current session and not capped by the --max-download-result option.
   535  func (c *client) GetGlobalStat() (info GlobalStatInfo, err error) {
   536  	params := []string{}
   537  	if c.token != "" {
   538  		params = append(params, "token:"+c.token)
   539  	}
   540  	err = c.Call(aria2GetGlobalStat, params, &info)
   541  	return
   542  }
   543  
   544  // `aria2.purgeDownloadResult([secret])`
   545  // This method purges completed/error/removed downloads to free memory.
   546  // This method returns OK.
   547  func (c *client) PurgeDownloadResult() (ok string, err error) {
   548  	params := []string{}
   549  	if c.token != "" {
   550  		params = append(params, "token:"+c.token)
   551  	}
   552  	err = c.Call(aria2PurgeDownloadResult, params, &ok)
   553  	return
   554  }
   555  
   556  // `aria2.removeDownloadResult([secret, ]gid)`
   557  // This method removes a completed/error/removed download denoted by gid from memory.
   558  // This method returns OK for success.
   559  func (c *client) RemoveDownloadResult(gid string) (ok string, err error) {
   560  	params := make([]interface{}, 0, 2)
   561  	if c.token != "" {
   562  		params = append(params, "token:"+c.token)
   563  	}
   564  	params = append(params, gid)
   565  	err = c.Call(aria2RemoveDownloadResult, params, &ok)
   566  	return
   567  }
   568  
   569  // `aria2.getVersion([secret])`
   570  // This method returns the version of aria2 and the list of enabled features.
   571  // The response is a struct and contains following keys.
   572  // 	version            Version number of aria2 as a string.
   573  // 	enabledFeatures    List of enabled features. Each feature is given as a string.
   574  func (c *client) GetVersion() (info VersionInfo, err error) {
   575  	params := []string{}
   576  	if c.token != "" {
   577  		params = append(params, "token:"+c.token)
   578  	}
   579  	err = c.Call(aria2GetVersion, params, &info)
   580  	return
   581  }
   582  
   583  // `aria2.getSessionInfo([secret])`
   584  // This method returns session information.
   585  // The response is a struct and contains following key.
   586  // 	sessionId    Session ID, which is generated each time when aria2 is invoked.
   587  func (c *client) GetSessionInfo() (info SessionInfo, err error) {
   588  	params := []string{}
   589  	if c.token != "" {
   590  		params = append(params, "token:"+c.token)
   591  	}
   592  	err = c.Call(aria2GetSessionInfo, params, &info)
   593  	return
   594  }
   595  
   596  // `aria2.shutdown([secret])`
   597  // This method shutdowns aria2.
   598  // This method returns OK.
   599  func (c *client) Shutdown() (ok string, err error) {
   600  	params := []string{}
   601  	if c.token != "" {
   602  		params = append(params, "token:"+c.token)
   603  	}
   604  	err = c.Call(aria2Shutdown, params, &ok)
   605  	return
   606  }
   607  
   608  // `aria2.forceShutdown([secret])`
   609  // This method shuts down aria2().
   610  // This method behaves like :func:'aria2.shutdown` without performing any actions which take time, such as contacting BitTorrent trackers to unregister downloads first.
   611  // This method returns OK.
   612  func (c *client) ForceShutdown() (ok string, err error) {
   613  	params := []string{}
   614  	if c.token != "" {
   615  		params = append(params, "token:"+c.token)
   616  	}
   617  	err = c.Call(aria2ForceShutdown, params, &ok)
   618  	return
   619  }
   620  
   621  // `aria2.saveSession([secret])`
   622  // This method saves the current session to a file specified by the --save-session option.
   623  // This method returns OK if it succeeds.
   624  func (c *client) SaveSession() (ok string, err error) {
   625  	params := []string{}
   626  	if c.token != "" {
   627  		params = append(params, "token:"+c.token)
   628  	}
   629  	err = c.Call(aria2SaveSession, params, &ok)
   630  	return
   631  }
   632  
   633  // `system.multicall(methods)`
   634  // This methods encapsulates multiple method calls in a single request.
   635  // methods is an array of structs.
   636  // The structs contain two keys: methodName and params.
   637  // methodName is the method name to call and params is array containing parameters to the method call.
   638  // This method returns an array of responses.
   639  // The elements will be either a one-item array containing the return value of the method call or a struct of fault element if an encapsulated method call fails.
   640  func (c *client) Multicall(methods []Method) (r []interface{}, err error) {
   641  	if len(methods) == 0 {
   642  		err = errInvalidParameter
   643  		return
   644  	}
   645  	err = c.Call(aria2Multicall, methods, &r)
   646  	return
   647  }
   648  
   649  // `system.listMethods()`
   650  // This method returns the all available RPC methods in an array of string.
   651  // Unlike other methods, this method does not require secret token.
   652  // This is safe because this method jsut returns the available method names.
   653  func (c *client) ListMethods() (methods []string, err error) {
   654  	err = c.Call(aria2ListMethods, []string{}, &methods)
   655  	return
   656  }