github.com/minio/madmin-go@v1.7.5/inspect.go (about) 1 // 2 // MinIO Object Storage (c) 2021 MinIO, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package madmin 18 19 import ( 20 "bufio" 21 "context" 22 "encoding/base64" 23 "errors" 24 "fmt" 25 "io" 26 "net/http" 27 "net/url" 28 ) 29 30 // InspectOptions provides options to Inspect. 31 type InspectOptions struct { 32 Volume, File string 33 PublicKey []byte // PublicKey to use for inspected data. 34 } 35 36 // Inspect makes an admin call to download a raw files from disk. 37 // If inspect is called with a public key no key will be returned 38 // and the data is returned encrypted with the public key. 39 func (adm *AdminClient) Inspect(ctx context.Context, d InspectOptions) (key []byte, c io.ReadCloser, err error) { 40 // Add form key/values in the body 41 form := make(url.Values) 42 form.Set("volume", d.Volume) 43 form.Set("file", d.File) 44 if d.PublicKey != nil { 45 form.Set("public-key", base64.StdEncoding.EncodeToString(d.PublicKey)) 46 } 47 48 method := "" 49 reqData := requestData{ 50 relPath: fmt.Sprintf(adminAPIPrefix + "/inspect-data"), 51 } 52 53 // If the public-key is specified, create a POST request and send 54 // parameters as multipart-form instead of query values 55 if d.PublicKey != nil { 56 method = http.MethodPost 57 reqData.customHeaders = make(http.Header) 58 reqData.customHeaders.Set("Content-Type", "application/x-www-form-urlencoded") 59 reqData.content = []byte(form.Encode()) 60 } else { 61 method = http.MethodGet 62 reqData.queryValues = form 63 } 64 65 resp, err := adm.executeMethod(ctx, method, reqData) 66 if err != nil { 67 return nil, nil, err 68 } 69 70 if resp.StatusCode != http.StatusOK { 71 closeResponse(resp) 72 return nil, nil, httpRespToErrorResponse(resp) 73 } 74 75 bior := bufio.NewReaderSize(resp.Body, 4<<10) 76 format, err := bior.ReadByte() 77 if err != nil { 78 closeResponse(resp) 79 return nil, nil, err 80 } 81 82 switch format { 83 case 1: 84 key = make([]byte, 32) 85 // Read key... 86 _, err = io.ReadFull(bior, key[:]) 87 if err != nil { 88 closeResponse(resp) 89 return nil, nil, err 90 } 91 case 2: 92 if err := bior.UnreadByte(); err != nil { 93 return nil, nil, err 94 } 95 default: 96 closeResponse(resp) 97 return nil, nil, errors.New("unknown data version") 98 } 99 100 // Return body 101 return key, &closeWrapper{Reader: bior, Closer: resp.Body}, nil 102 } 103 104 type closeWrapper struct { 105 io.Reader 106 io.Closer 107 }