Skip to content

Instantly share code, notes, and snippets.

@aki237
Created April 14, 2017 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aki237/db3af007c048d6e61a15d5c256cf69ac to your computer and use it in GitHub Desktop.
Save aki237/db3af007c048d6e61a15d5c256cf69ac to your computer and use it in GitHub Desktop.
func Out(file *os.File, c *sync.WaitGroup, nth int, from, size int64, written chan int64) {
// Parameters :
// + file *os.File : temp file where contents have to be written.
// + c *sync.WaitGroup : To inform the main function that this connection has ended....
// + nth int : Nth connection. Not needed. but say ou want to print nth connection failed or
// something like that.
// + from int64 : from which byte
// + size int64 : how much have to returned
// + written chan int64 : as said before used send how much have been written from various connections.
// Make new request. I know it is a bad bad practice to access os.Args like this...
// Come on this is just a prototype.
r, err := http.NewRequest("GET", os.Args[1], nil)
check err
// Here is the MEATY part. Set the Range Header.....
r.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", from, from+size))
// Execute the request.
resp, err := http.DefaultClient.Do(r)
check err
// Make a byte buffer. for reading in each cycle...
// You should know this if you have done Go.
// I'm not `io.Copy`ing because I want to know how much have been
// written to be sent through channel `written`.
// But the following loop is stolen from io.Copy source code.. :P
buf := make([]byte, 32*1024)
for {
nr, er := resp.Body.Read(buf) // read from response body.
if nr > 0 {
// if something read ? then write it to the temp file passed as parameter.
nw, ew := file.Write(buf[0:nr])
// Send how much have been written in the file..... through that channel.
if nw > 0 {
written <- int64(nw)
}
// Err??? check err.
// Go people really don't like errors I guess.... ew :P
// Well, who does??
check ew
// If read amount is not written, that an error...
// check that too....
if nr != nw {
check errors.New("Error short write")
// This is not a syntax like return.... I'm just lazy to write the whole thing...
}
}
// if any error in readin from resp? no worries get out of the loop.
if er != nil {
break
}
}
// Close remote connection
resp.Body.Close()
// Close the local temp file...
file.Close()
// Say the Job controller or the WaitGroup this Job is done....
c.Done()
// Thats it....
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment