gopkg.in/cavaliercoder/grab.v2@v2.0.0/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 // NoCreateDirectories specifies that any missing directories in the given 55 // Filename path should not be created automatically, if they do not already 56 // exist. 57 NoCreateDirectories bool 58 59 // IgnoreBadStatusCodes specifies that grab should accept any status code in 60 // the response from the remote server. Otherwise, grab expects the response 61 // status code to be within the 2XX range (after following redirects). 62 IgnoreBadStatusCodes bool 63 64 // IgnoreRemoteTime specifies that grab should not attempt to set the 65 // timestamp of the local file to match the remote file. 66 IgnoreRemoteTime bool 67 68 // Size specifies the expected size of the file transfer if known. If the 69 // server response size does not match, the transfer is cancelled and 70 // ErrBadLength returned. 71 Size int64 72 73 // BufferSize specifies the size in bytes of the buffer that is used for 74 // transferring the requested file. Larger buffers may result in faster 75 // throughput but will use more memory and result in less frequent updates 76 // to the transfer progress statistics. If a RateLimiter is configured, 77 // BufferSize should be much lower than the rate limit. Default: 32KB. 78 BufferSize int 79 80 // RateLimiter allows the transfer rate of a download to be limited. The given 81 // Request.BufferSize determines how frequently the RateLimiter will be 82 // polled. 83 RateLimiter RateLimiter 84 85 // BeforeCopy is a user provided callback that is called immediately before 86 // a request starts downloading. If BeforeCopy returns an error, the request 87 // is cancelled and the same error is returned on the Response object. 88 BeforeCopy Hook 89 90 // AfterCopy is a user provided callback that is called immediately after a 91 // request has finished downloading, before checksum validation and closure. 92 // This hook is only called if the transfer was successful. If AfterCopy 93 // returns an error, the request is canceled and the same error is returned on 94 // the Response object. 95 AfterCopy Hook 96 97 // hash, checksum and deleteOnError - set via SetChecksum. 98 hash hash.Hash 99 checksum []byte 100 deleteOnError bool 101 102 // Context for cancellation and timeout - set via WithContext 103 ctx context.Context 104 } 105 106 // NewRequest returns a new file transfer Request suitable for use with 107 // Client.Do. 108 func NewRequest(dst, urlStr string) (*Request, error) { 109 if dst == "" { 110 dst = "." 111 } 112 req, err := http.NewRequest("GET", urlStr, nil) 113 if err != nil { 114 return nil, err 115 } 116 return &Request{ 117 HTTPRequest: req, 118 Filename: dst, 119 }, nil 120 } 121 122 // Context returns the request's context. To change the context, use 123 // WithContext. 124 // 125 // The returned context is always non-nil; it defaults to the background 126 // context. 127 // 128 // The context controls cancelation. 129 func (r *Request) Context() context.Context { 130 if r.ctx != nil { 131 return r.ctx 132 } 133 134 return context.Background() 135 } 136 137 // WithContext returns a shallow copy of r with its context changed 138 // to ctx. The provided ctx must be non-nil. 139 func (r *Request) WithContext(ctx context.Context) *Request { 140 if ctx == nil { 141 panic("nil context") 142 } 143 r2 := new(Request) 144 *r2 = *r 145 r2.ctx = ctx 146 r2.HTTPRequest = r2.HTTPRequest.WithContext(ctx) 147 return r2 148 } 149 150 // URL returns the URL to be downloaded. 151 func (r *Request) URL() *url.URL { 152 return r.HTTPRequest.URL 153 } 154 155 // SetChecksum sets the desired hashing algorithm and checksum value to validate 156 // a downloaded file. Once the download is complete, the given hashing algorithm 157 // will be used to compute the actual checksum of the downloaded file. If the 158 // checksums do not match, an error will be returned by the associated 159 // Response.Err method. 160 // 161 // If deleteOnError is true, the downloaded file will be deleted automatically 162 // if it fails checksum validation. 163 // 164 // To prevent corruption of the computed checksum, the given hash must not be 165 // used by any other request or goroutines. 166 // 167 // To disable checksum validation, call SetChecksum with a nil hash. 168 func (r *Request) SetChecksum(h hash.Hash, sum []byte, deleteOnError bool) { 169 r.hash = h 170 r.checksum = sum 171 r.deleteOnError = deleteOnError 172 }