github.com/cavaliergopher/grab/v3@v3.0.1/request.go (about) 1 package grab 2 3 import ( 4 "context" 5 "hash" 6 "net/http" 7 "net/url" 8 ) 9 10 // A Hook is a user provided callback function that can be called by grab at 11 // various stages of a requests lifecycle. If a hook returns an error, the 12 // associated request is canceled and the same error is returned on the Response 13 // object. 14 // 15 // Hook functions are called synchronously and should never block unnecessarily. 16 // Response methods that block until a download is complete, such as 17 // Response.Err, Response.Cancel or Response.Wait will deadlock. To cancel a 18 // download from a callback, simply return a non-nil error. 19 type Hook func(*Response) error 20 21 // A Request represents an HTTP file transfer request to be sent by a Client. 22 type Request struct { 23 // Label is an arbitrary string which may used to label a Request with a 24 // user friendly name. 25 Label string 26 27 // Tag is an arbitrary interface which may be used to relate a Request to 28 // other data. 29 Tag interface{} 30 31 // HTTPRequest specifies the http.Request to be sent to the remote server to 32 // initiate a file transfer. It includes request configuration such as URL, 33 // protocol version, HTTP method, request headers and authentication. 34 HTTPRequest *http.Request 35 36 // Filename specifies the path where the file transfer will be stored in 37 // local storage. If Filename is empty or a directory, the true Filename will 38 // be resolved using Content-Disposition headers or the request URL. 39 // 40 // An empty string means the transfer will be stored in the current working 41 // directory. 42 Filename string 43 44 // SkipExisting specifies that ErrFileExists should be returned if the 45 // destination path already exists. The existing file will not be checked for 46 // completeness. 47 SkipExisting bool 48 49 // NoResume specifies that a partially completed download will be restarted 50 // without attempting to resume any existing file. If the download is already 51 // completed in full, it will not be restarted. 52 NoResume bool 53 54 // NoStore specifies that grab should not write to the local file system. 55 // Instead, the download will be stored in memory and accessible only via 56 // Response.Open or Response.Bytes. 57 NoStore bool 58 59 // NoCreateDirectories specifies that any missing directories in the given 60 // Filename path should not be created automatically, if they do not already 61 // exist. 62 NoCreateDirectories bool 63 64 // IgnoreBadStatusCodes specifies that grab should accept any status code in 65 // the response from the remote server. Otherwise, grab expects the response 66 // status code to be within the 2XX range (after following redirects). 67 IgnoreBadStatusCodes bool 68 69 // IgnoreRemoteTime specifies that grab should not attempt to set the 70 // timestamp of the local file to match the remote file. 71 IgnoreRemoteTime bool 72 73 // Size specifies the expected size of the file transfer if known. If the 74 // server response size does not match, the transfer is cancelled and 75 // ErrBadLength returned. 76 Size int64 77 78 // BufferSize specifies the size in bytes of the buffer that is used for 79 // transferring the requested file. Larger buffers may result in faster 80 // throughput but will use more memory and result in less frequent updates 81 // to the transfer progress statistics. If a RateLimiter is configured, 82 // BufferSize should be much lower than the rate limit. Default: 32KB. 83 BufferSize int 84 85 // RateLimiter allows the transfer rate of a download to be limited. The given 86 // Request.BufferSize determines how frequently the RateLimiter will be 87 // polled. 88 RateLimiter RateLimiter 89 90 // BeforeCopy is a user provided callback that is called immediately before 91 // a request starts downloading. If BeforeCopy returns an error, the request 92 // is cancelled and the same error is returned on the Response object. 93 BeforeCopy Hook 94 95 // AfterCopy is a user provided callback that is called immediately after a 96 // request has finished downloading, before checksum validation and closure. 97 // This hook is only called if the transfer was successful. If AfterCopy 98 // returns an error, the request is canceled and the same error is returned on 99 // the Response object. 100 AfterCopy Hook 101 102 // hash, checksum and deleteOnError - set via SetChecksum. 103 hash hash.Hash 104 checksum []byte 105 deleteOnError bool 106 107 // Context for cancellation and timeout - set via WithContext 108 ctx context.Context 109 } 110 111 // NewRequest returns a new file transfer Request suitable for use with 112 // Client.Do. 113 func NewRequest(dst, urlStr string) (*Request, error) { 114 if dst == "" { 115 dst = "." 116 } 117 req, err := http.NewRequest("GET", urlStr, nil) 118 if err != nil { 119 return nil, err 120 } 121 return &Request{ 122 HTTPRequest: req, 123 Filename: dst, 124 }, nil 125 } 126 127 // Context returns the request's context. To change the context, use 128 // WithContext. 129 // 130 // The returned context is always non-nil; it defaults to the background 131 // context. 132 // 133 // The context controls cancelation. 134 func (r *Request) Context() context.Context { 135 if r.ctx != nil { 136 return r.ctx 137 } 138 139 return context.Background() 140 } 141 142 // WithContext returns a shallow copy of r with its context changed 143 // to ctx. The provided ctx must be non-nil. 144 func (r *Request) WithContext(ctx context.Context) *Request { 145 if ctx == nil { 146 panic("nil context") 147 } 148 r2 := new(Request) 149 *r2 = *r 150 r2.ctx = ctx 151 r2.HTTPRequest = r2.HTTPRequest.WithContext(ctx) 152 return r2 153 } 154 155 // URL returns the URL to be downloaded. 156 func (r *Request) URL() *url.URL { 157 return r.HTTPRequest.URL 158 } 159 160 // SetChecksum sets the desired hashing algorithm and checksum value to validate 161 // a downloaded file. Once the download is complete, the given hashing algorithm 162 // will be used to compute the actual checksum of the downloaded file. If the 163 // checksums do not match, an error will be returned by the associated 164 // Response.Err method. 165 // 166 // If deleteOnError is true, the downloaded file will be deleted automatically 167 // if it fails checksum validation. 168 // 169 // To prevent corruption of the computed checksum, the given hash must not be 170 // used by any other request or goroutines. 171 // 172 // To disable checksum validation, call SetChecksum with a nil hash. 173 func (r *Request) SetChecksum(h hash.Hash, sum []byte, deleteOnError bool) { 174 r.hash = h 175 r.checksum = sum 176 r.deleteOnError = deleteOnError 177 }