request b2_download_file_by_name if listing a single file with no versions

This commit is contained in:
Arno Hautala
2017-09-20 14:32:09 -04:00
committed by GitHub
parent 6bffef36bf
commit bb1a15382e

View File

@@ -82,7 +82,7 @@ func (client *B2Client) retry(backoff int, response *http.Response) int {
return backoff return backoff
} }
func (client *B2Client) call(url string, input interface{}) (io.ReadCloser, int64, error) { func (client *B2Client) call(url string, requestHeaders map[string]string, input interface{}) (io.ReadCloser, Header, int64, error) {
var response *http.Response var response *http.Response
@@ -95,7 +95,7 @@ func (client *B2Client) call(url string, input interface{}) (io.ReadCloser, int6
default: default:
jsonInput, err := json.Marshal(input) jsonInput, err := json.Marshal(input)
if err != nil { if err != nil {
return nil, 0, err return nil, nil, 0, err
} }
inputReader = bytes.NewReader(jsonInput) inputReader = bytes.NewReader(jsonInput)
case []byte: case []byte:
@@ -103,11 +103,14 @@ func (client *B2Client) call(url string, input interface{}) (io.ReadCloser, int6
case int: case int:
method = "GET" method = "GET"
inputReader = bytes.NewReader([]byte("")) inputReader = bytes.NewReader([]byte(""))
case nil:
method = "HEAD"
inputReader = bytes.NewReader([]byte(""))
} }
request, err := http.NewRequest(method, url, inputReader) request, err := http.NewRequest(method, url, inputReader)
if err != nil { if err != nil {
return nil, 0, err return nil, nil, 0, err
} }
if url == B2AuthorizationURL { if url == B2AuthorizationURL {
@@ -116,6 +119,10 @@ func (client *B2Client) call(url string, input interface{}) (io.ReadCloser, int6
request.Header.Set("Authorization", client.AuthorizationToken) request.Header.Set("Authorization", client.AuthorizationToken)
} }
for k, v := range requestHeaders {
request.Header.Set(k, v)
}
if client.TestMode { if client.TestMode {
r := rand.Float32() r := rand.Float32()
if r < 0.5 { if r < 0.5 {
@@ -132,11 +139,11 @@ func (client *B2Client) call(url string, input interface{}) (io.ReadCloser, int6
backoff = client.retry(backoff, response) backoff = client.retry(backoff, response)
continue continue
} }
return nil, 0, err return nil, nil, 0, err
} }
if response.StatusCode < 300 { if response.StatusCode < 300 {
return response.Body, response.ContentLength, nil return response.Body, response.Header, response.ContentLength, nil
} }
LOG_DEBUG("BACKBLAZE_CALL", "URL request '%s' returned status code %d", url, response.StatusCode) LOG_DEBUG("BACKBLAZE_CALL", "URL request '%s' returned status code %d", url, response.StatusCode)
@@ -145,13 +152,13 @@ func (client *B2Client) call(url string, input interface{}) (io.ReadCloser, int6
response.Body.Close() response.Body.Close()
if response.StatusCode == 401 { if response.StatusCode == 401 {
if url == B2AuthorizationURL { if url == B2AuthorizationURL {
return nil, 0, fmt.Errorf("Authorization failure") return nil, nil, 0, fmt.Errorf("Authorization failure")
} }
client.AuthorizeAccount() client.AuthorizeAccount()
continue continue
} else if response.StatusCode == 403 { } else if response.StatusCode == 403 {
if !client.TestMode { if !client.TestMode {
return nil, 0, fmt.Errorf("B2 cap exceeded") return nil, nil, 0, fmt.Errorf("B2 cap exceeded")
} }
continue continue
} else if response.StatusCode == 429 || response.StatusCode == 408 { } else if response.StatusCode == 429 || response.StatusCode == 408 {
@@ -172,13 +179,13 @@ func (client *B2Client) call(url string, input interface{}) (io.ReadCloser, int6
} }
if err := json.NewDecoder(response.Body).Decode(e); err != nil { if err := json.NewDecoder(response.Body).Decode(e); err != nil {
return nil, 0, err return nil, nil, 0, err
} }
return nil, 0, e return nil, nil, 0, e
} }
return nil, 0, fmt.Errorf("Maximum backoff reached") return nil, nil, 0, fmt.Errorf("Maximum backoff reached")
} }
type B2AuthorizeAccountOutput struct { type B2AuthorizeAccountOutput struct {
@@ -287,12 +294,19 @@ func (client *B2Client) ListFileNames(startFileName string, singleFile bool, inc
input["startFileName"] = startFileName input["startFileName"] = startFileName
input["maxFileCount"] = maxFileCount input["maxFileCount"] = maxFileCount
url := client.APIURL + "/b2api/v1/b2_list_file_names"
requestHeaders := map[string]string{}
if includeVersions {
url = client.APIURL + "/b2api/v1/b2_list_file_versions"
} else if singleFile {
// handle a single file with no versions as a special case to download the first byte of the file
url = client.APIURL + "/b2api/v1/b2_download_file_by_name"
requestHeaders["Range"] = "bytes=0-0"
// HEAD request
input = nil
}
for { for {
url := client.APIURL + "/b2api/v1/b2_list_file_names" readCloser, responseHeader, _, err := client.call(url, requestHeaders, input)
if includeVersions {
url = client.APIURL + "/b2api/v1/b2_list_file_versions"
}
readCloser, _, err := client.call(url, input)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -302,6 +316,17 @@ func (client *B2Client) ListFileNames(startFileName string, singleFile bool, inc
output := B2ListFileNamesOutput { output := B2ListFileNamesOutput {
} }
if singleFile && !includeVersions {
// construct the B2Entry from the response headers of the download request
file := B2Entry
file.FileID = responseHeader().Get("X-Bz-File-Id")
file.FileName = responseHeader().Get("X-Bz-File-Name")
file.Action = responseHeader().Get("X-Bz-Action")
file.Size = responseHeader().Get("Content-Length")
file.UploadTimestamp = responseHeader().Get("X-Bz-Upload-Timestamp")
return []*B2Entry{file}
}
if err = json.NewDecoder(readCloser).Decode(&output); err != nil { if err = json.NewDecoder(readCloser).Decode(&output); err != nil {
return nil, err return nil, err
} }