Решение на HTTP сваляч от Константин Тодоров

Обратно към всички решения

Към профила на Константин Тодоров

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 9 успешни тест(а)
  • 8 неуспешни тест(а)

Код

package main
import (
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"strconv"
)
var noValidUrls = "no valid urls"
func getFileLengthFromURL(url string) int {
res, err := http.Head(url)
if err != nil {
return 0
}
contentLength, err := strconv.Atoi(res.Header.Get("Content-Length"))
if err != nil {
return 0
}
return contentLength
}
func getBytesEnd(r Reader) int {
if len(r.urls)-len(r.invalidUrls) == 1 {
return r.fileBytesCount - 1
}
if r.fileBytesCount > 0 && r.readIndex+1 > r.fileBytesCount-1 {
return r.fileBytesCount - 1
}
return r.readIndex + 1
}
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
func getUrlWithLowestBytesRead(r Reader) string {
var minBytesRead = 0
var minURL = ""
for url, bytesRead := range r.urls {
if !contains(r.invalidUrls, url) && bytesRead == 0 {
return url
} else if !contains(r.invalidUrls, url) && (minBytesRead > bytesRead || minBytesRead == 0) {
minBytesRead = bytesRead
minURL = url
}
}
return minURL
}
type Reader struct {
data []byte
readIndex int
urls map[string]int
invalidUrls []string
fileBytesCount int
calledServer bool
}
func CreateReader(urls []string) io.Reader {
var reader = new(Reader)
reader.urls = make(map[string]int)
for _, url := range urls {
reader.urls[url] = 0
}
reader.fileBytesCount = -1
reader.calledServer = false
reader.invalidUrls = []string{}
return reader
}
func (r *Reader) Read(p []byte) (int, error) {
if r.urls == nil || r.fileBytesCount == 0 {
return 0, errors.New("error")
}
if r.calledServer && r.readIndex > r.fileBytesCount-1 {
return 0, io.EOF
}
var bytesRead, err = r.readFromUrls()
if err != nil {
if bytesRead > 0 {
copy(p, r.data[r.readIndex-bytesRead:])
}
if len(r.urls)-len(r.invalidUrls) == 0 {
return bytesRead, errors.New(noValidUrls)
}
return bytesRead, err
}
var n = copy(p, r.data[r.readIndex-bytesRead:])
return n, nil
}
func (r *Reader) readFromUrls() (int, error) {
var bytesRead int
var url = getUrlWithLowestBytesRead(*r)
if !r.calledServer {
r.fileBytesCount = getFileLengthFromURL(url)
r.calledServer = true
}
for url != "" {
if !contains(r.invalidUrls, url) && r.readIndex < r.fileBytesCount {
contents, contentLength, err := r.readFromUrl(url)
if contents != nil && len(contents) > 0 {
var trimmedContents = contents[0:contentLength]
r.data = append(r.data, trimmedContents...)
r.readIndex = r.readIndex + contentLength
bytesRead = bytesRead + contentLength
r.urls[url] = r.urls[url] + contentLength
}
if err != nil {
return bytesRead, err
}
}
if r.readIndex >= r.fileBytesCount {
return bytesRead, nil
}
url = getUrlWithLowestBytesRead(*r)
}
return bytesRead, nil
}
func (r *Reader) readFromUrl(url string) ([]byte, int, error) {
var contents = []byte{}
var contentLength = 0
var bytesEnd = getBytesEnd(*r)
var bytesStart = r.readIndex
for len(contents) == 0 {
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, 0, err
}
var rangeHeader = fmt.Sprintf("bytes=%d-%d", bytesStart, bytesEnd)
req.Header.Add("Range", rangeHeader)
res, err := client.Do(req)
if err != nil {
return nil, 0, err
}
if res != nil && res.StatusCode >= 400 {
r.invalidUrls = append(r.invalidUrls, []string{url}...)
return nil, 0, nil
}
contents, err = ioutil.ReadAll(res.Body)
if err != nil {
r.invalidUrls = append(r.invalidUrls, []string{url}...)
return contents, len(contents), err
}
if len(contents) > 0 {
res.Body.Close()
}
contentLength, err = strconv.Atoi(res.Header.Get("Content-Length"))
if err != nil {
return nil, 0, err
}
}
return contents, contentLength, nil
}
func DownloadFile(ctx context.Context, urls []string) io.Reader {
var reader = CreateReader(urls)
return reader
}

Лог от изпълнението

--- FAIL: TestNothingIsReturned (0.00s)
	solution_test.go:47: Expected to get error 'EOF', but got 'error'
FAIL
exit status 1
FAIL	_/tmp/d20170109-30451-11e94cp	0.006s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.006s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.006s
panic: test timed out after 1s

goroutine 20 [running]:
panic(0x668ee0, 0xc42015e600)
	/usr/local/go/src/runtime/panic.go:500 +0x1a1
testing.startAlarm.func1()
	/usr/local/go/src/testing/testing.go:918 +0x10b
created by time.goFunc
	/usr/local/go/src/time/sleep.go:154 +0x44

goroutine 1 [chan receive]:
testing.(*T).Run(0xc42007c0c0, 0x6d7995, 0x32, 0x6f0590, 0xc42004bd01)
	/usr/local/go/src/testing/testing.go:647 +0x316
testing.RunTests.func1(0xc42007c0c0)
	/usr/local/go/src/testing/testing.go:793 +0x6d
testing.tRunner(0xc42007c0c0, 0xc42003de30)
	/usr/local/go/src/testing/testing.go:610 +0x81
testing.RunTests(0x6f0778, 0x803140, 0x11, 0x11, 0x7f44737fa000)
	/usr/local/go/src/testing/testing.go:799 +0x2f5
testing.(*M).Run(0xc42003def8, 0x686de0)
	/usr/local/go/src/testing/testing.go:743 +0x85
main.main()
	_/tmp/d20170109-30451-11e94cp/_test/_testmain.go:86 +0xc6

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2086 +0x1

goroutine 6 [select]:
net/http.(*persistConn).roundTrip(0xc42000a900, 0xc42014b0c0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:1840 +0x93b
net/http.(*Transport).RoundTrip(0xc4200c2000, 0xc420164870, 0xc4200c2000, 0x0, 0x0)
	/usr/local/go/src/net/http/transport.go:380 +0x4ee
net/http.send(0xc420164870, 0x7e6ea0, 0xc4200c2000, 0x0, 0x0, 0x0, 0x8, 0xc42004d8e8, 0xc42013c380)
	/usr/local/go/src/net/http/client.go:256 +0x15f
net/http.(*Client).send(0xc42004dba8, 0xc420164870, 0x0, 0x0, 0x0, 0xc42013c380, 0x0, 0x1)
	/usr/local/go/src/net/http/client.go:146 +0x102
net/http.(*Client).doFollowingRedirects(0xc42004dba8, 0xc420164870, 0x6f0af0, 0x3, 0x51f001, 0xc42015d440)
	/usr/local/go/src/net/http/client.go:528 +0x5e5
net/http.(*Client).Do(0xc42004dba8, 0xc420164870, 0x5, 0xc420137920, 0xb)
	/usr/local/go/src/net/http/client.go:184 +0x1ea
_/tmp/d20170109-30451-11e94cp.(*Reader).readFromUrl(0xc42001c690, 0xc4200be9c0, 0x1c, 0xc4200be9c0, 0x1c, 0x822900, 0x0, 0x0, 0x25)
	/tmp/d20170109-30451-11e94cp/solution.go:161 +0x2b4
_/tmp/d20170109-30451-11e94cp.(*Reader).readFromUrls(0xc42001c690, 0x0, 0x0, 0xc42000d140)
	/tmp/d20170109-30451-11e94cp/solution.go:123 +0x192
_/tmp/d20170109-30451-11e94cp.(*Reader).Read(0xc42001c690, 0xc420016400, 0x200, 0x200, 0x1c, 0xc42003bdf0, 0x47778f)
	/tmp/d20170109-30451-11e94cp/solution.go:96 +0xd8
bytes.(*Buffer).ReadFrom(0xc42004dee8, 0x7e6860, 0xc42001c690, 0x1, 0x1, 0x7e6860)
	/usr/local/go/src/bytes/buffer.go:176 +0x155
_/tmp/d20170109-30451-11e94cp.TestSingleURLCancelContextAfterHalfBytesWereServed(0xc42007c180)
	/tmp/d20170109-30451-11e94cp/solution_test.go:193 +0x2dd
testing.tRunner(0xc42007c180, 0x6f0590)
	/usr/local/go/src/testing/testing.go:610 +0x81
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:646 +0x2ec

goroutine 7 [IO wait]:
net.runtime_pollWait(0x7f447379f178, 0x72, 0x0)
	/usr/local/go/src/runtime/netpoll.go:160 +0x59
net.(*pollDesc).wait(0xc420014370, 0x72, 0xc4200285e0, 0xc4200121b0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x38
net.(*pollDesc).waitRead(0xc420014370, 0x7e88a0, 0xc4200121b0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x34
net.(*netFD).accept(0xc420014310, 0x0, 0x7e74a0, 0xc4200d60a0)
	/usr/local/go/src/net/fd_unix.go:419 +0x238
net.(*TCPListener).accept(0xc42002a048, 0x43413e, 0xc420028690, 0x52d48d)
	/usr/local/go/src/net/tcpsock_posix.go:132 +0x2e
net.(*TCPListener).Accept(0xc42002a048, 0x6f0958, 0xc4200f0000, 0x7eb420, 0xc4200dc060)
	/usr/local/go/src/net/tcpsock.go:222 +0x49
net/http.(*Server).Serve(0xc42001a300, 0x7eaba0, 0xc42002a048, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:2273 +0x1ce
net/http/httptest.(*Server).goServe.func1(0xc42005e4e0)
	/usr/local/go/src/net/http/httptest/server.go:235 +0x6d
created by net/http/httptest.(*Server).goServe
	/usr/local/go/src/net/http/httptest/server.go:236 +0x5c

goroutine 10 [IO wait]:
net.runtime_pollWait(0x7f447379f0b8, 0x72, 0x5)
	/usr/local/go/src/runtime/netpoll.go:160 +0x59
net.(*pollDesc).wait(0xc420014450, 0x72, 0xc42003b9d0, 0xc4200121b0)
	/usr/local/go/src/net/fd_poll_runtime.go:73 +0x38
net.(*pollDesc).waitRead(0xc420014450, 0x7e88a0, 0xc4200121b0)
	/usr/local/go/src/net/fd_poll_runtime.go:78 +0x34
net.(*netFD).Read(0xc4200143f0, 0xc420083000, 0x1000, 0x1000, 0x0, 0x7e88a0, 0xc4200121b0)
	/usr/local/go/src/net/fd_unix.go:243 +0x1a1
net.(*conn).Read(0xc42002a068, 0xc420083000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:173 +0x70
net/http.(*persistConn).Read(0xc42000a900, 0xc420083000, 0x1000, 0x1000, 0x30, 0xc42003bb58, 0x43b1ec)
	/usr/local/go/src/net/http/transport.go:1261 +0x154
bufio.(*Reader).fill(0xc42005ea20)
	/usr/local/go/src/bufio/bufio.go:97 +0x10c
bufio.(*Reader).Peek(0xc42005ea20, 0x1, 0x0, 0x1, 0x0, 0xc420145d40, 0x0)
	/usr/local/go/src/bufio/bufio.go:129 +0x62
net/http.(*persistConn).readLoop(0xc42000a900)
	/usr/local/go/src/net/http/transport.go:1418 +0x1a1
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:1062 +0x4e9

goroutine 11 [select]:
net/http.(*persistConn).writeLoop(0xc42000a900)
	/usr/local/go/src/net/http/transport.go:1646 +0x3bd
created by net/http.(*Transport).dialConn
	/usr/local/go/src/net/http/transport.go:1063 +0x50e

goroutine 18 [runnable]:
syscall.Syscall(0x0, 0x6, 0xc4200f6000, 0x1000, 0x62, 0x1000, 0x0)
	/usr/local/go/src/syscall/asm_linux_amd64.s:18 +0x5
syscall.read(0x6, 0xc4200f6000, 0x1000, 0x1000, 0x72, 0x0, 0x0)
	/usr/local/go/src/syscall/zsyscall_linux_amd64.go:783 +0x55
syscall.Read(0x6, 0xc4200f6000, 0x1000, 0x1000, 0xffffffffffffff01, 0x7e88a0, 0xc4200121b0)
	/usr/local/go/src/syscall/syscall_unix.go:161 +0x49
net.(*netFD).Read(0xc4200ec000, 0xc4200f6000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/fd_unix.go:239 +0x10f
net.(*conn).Read(0xc4200ee000, 0xc4200f6000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:173 +0x70
net/http.(*connReader).Read(0xc4200d60c0, 0xc4200f6000, 0x1000, 0x1000, 0xc420036918, 0x6d0c6b, 0x19)
	/usr/local/go/src/net/http/server.go:586 +0x144
bufio.(*Reader).fill(0xc4200f4000)
	/usr/local/go/src/bufio/bufio.go:97 +0x10c
bufio.(*Reader).ReadSlice(0xc4200f4000, 0xa, 0x0, 0x1e, 0xa, 0x33, 0x0)
	/usr/local/go/src/bufio/bufio.go:330 +0xb5
bufio.(*Reader).ReadLine(0xc4200f4000, 0xc42015b2c0, 0xf0, 0xf0, 0x6c0c80, 0x49ff93, 0x805d78)
	/usr/local/go/src/bufio/bufio.go:359 +0x37
net/textproto.(*Reader).readLineSlice(0xc4200dc150, 0xc420036aa8, 0xc420036aa8, 0x410688, 0xf0, 0x6c0c80)
	/usr/local/go/src/net/textproto/reader.go:55 +0x5e
net/textproto.(*Reader).ReadLine(0xc4200dc150, 0xc42015b2c0, 0xc420036b20, 0x401863, 0xc420036c78)
	/usr/local/go/src/net/textproto/reader.go:36 +0x2f
net/http.readRequest(0xc4200f4000, 0xc420036c00, 0xc42015b2c0, 0x0, 0x0)
	/usr/local/go/src/net/http/request.go:793 +0xa5
net/http.(*conn).readRequest(0xc4200f0000, 0x7eb360, 0xc4200d2140, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/server.go:765 +0x10d
net/http.(*conn).serve(0xc4200f0000, 0x7eb360, 0xc4200d2140)
	/usr/local/go/src/net/http/server.go:1532 +0x3d3
created by net/http.(*Server).Serve
	/usr/local/go/src/net/http/server.go:2293 +0x44d
exit status 2
FAIL	_/tmp/d20170109-30451-11e94cp	1.010s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.010s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.006s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.010s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.010s
--- FAIL: TestTwoUrlsWithOneBroken (0.01s)
	solution_test.go:436: Expected to read 37 bytes from simple download but got 2
	solution_test.go:440: Expected to get no error, but got 'Get http://some.non.existing.domain.at.nowhere/pesho: dial tcp: lookup some.non.existing.domain.at.nowhere on 192.168.1.1:53: no such host'
	solution_test.go:53: Expected result was '5468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e7365' but got '5468'
FAIL
exit status 1
FAIL	_/tmp/d20170109-30451-11e94cp	0.011s
--- FAIL: TestTwoUrlsWithTheOtherOneBroken (0.00s)
	solution_test.go:481: Expected to read 37 bytes from simple download but got 0
	solution_test.go:485: Expected to get no error, but got 'error'
	solution_test.go:53: Expected result was '5468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e7365' but got ''
FAIL
exit status 1
FAIL	_/tmp/d20170109-30451-11e94cp	0.010s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.008s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.013s
PASS
ok  	_/tmp/d20170109-30451-11e94cp	0.013s
--- FAIL: TestTwoUrlsWithOneByteReader (0.00s)
	solution_test.go:744: Expected to read 37 bytes from simple download but got 1
	solution_test.go:53: Expected result was '5468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e7365' but got '54'
	solution_test.go:756: It was expected that the downloaded amount from both urls  will be equal to the size of the request but while it was 1, from url[0] was downloaded 19 and from url[1] 18
FAIL
exit status 1
FAIL	_/tmp/d20170109-30451-11e94cp	0.010s
--- FAIL: TestLingchi (0.07s)
	solution_test.go:821: Expected to read 500 bytes from simple download but got 1
	solution_test.go:53: Expected result was '5468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f7374206570' but got '54'
	solution_test.go:832: From url with index 0 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 1 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 2 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 3 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 4 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 5 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 6 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 7 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 8 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 9 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 10 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 11 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 12 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 13 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 14 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 15 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 16 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 17 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 18 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 19 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 20 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 21 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 22 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 23 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 24 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 25 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 26 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 27 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 28 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 29 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 30 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 31 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 32 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 33 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 34 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 35 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 36 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 37 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 38 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 39 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 40 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 41 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 42 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 43 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 44 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 45 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 46 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 47 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 48 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 49 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 50 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 51 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 52 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 53 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 54 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 55 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 56 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 57 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 58 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 59 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 60 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 61 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 62 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 63 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 64 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 65 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 66 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 67 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 68 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 69 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 70 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 71 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 72 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 73 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 74 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 75 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 76 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 77 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 78 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 79 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 80 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 81 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 82 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 83 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 84 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 85 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 86 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 87 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 88 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 89 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 90 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 91 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 92 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 93 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 94 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 95 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 96 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 97 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 98 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 99 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 100 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 101 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 102 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 103 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 104 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 105 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 106 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 107 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 108 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 109 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 110 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 111 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 112 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 113 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 114 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 115 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 116 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 117 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 118 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 119 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 120 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 121 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 122 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 123 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 124 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 125 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 126 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 127 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 128 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 129 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 130 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 131 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 132 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 133 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 134 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 135 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 136 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 137 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 138 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 139 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 140 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 141 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 142 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 143 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 144 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 145 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 146 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 147 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 148 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 149 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 150 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 151 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 152 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 153 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 154 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 155 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 156 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 157 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 158 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 159 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 160 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 161 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 162 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 163 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 164 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 165 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 166 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 167 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 168 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 169 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 170 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 171 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 172 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 173 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 174 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 175 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 176 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 177 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 178 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 179 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 180 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 181 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 182 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 183 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 184 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 185 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 186 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 187 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 188 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 189 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 190 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 191 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 192 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 193 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 194 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 195 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 196 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 197 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 198 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 199 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 200 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 201 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 202 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 203 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 204 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 205 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 206 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 207 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 208 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 209 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 210 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 211 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 212 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 213 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 214 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 215 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 216 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 217 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 218 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 219 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 220 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 221 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 222 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 223 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 224 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 225 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 226 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 227 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 228 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 229 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 230 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 231 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 232 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 233 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 234 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 235 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 236 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 237 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 238 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 239 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 240 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 241 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 242 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 243 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 244 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 245 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 246 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 247 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 248 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 249 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 250 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 251 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 252 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 253 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 254 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 255 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 256 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 257 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 258 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 259 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 260 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 261 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 262 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 263 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 264 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 265 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 266 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 267 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 268 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 269 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 270 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 271 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 272 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 273 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 274 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 275 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 276 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 277 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 278 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 279 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 280 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 281 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 282 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 283 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 284 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 285 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 286 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 287 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 288 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 289 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 290 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 291 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 292 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 293 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 294 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 295 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 296 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 297 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 298 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 299 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 300 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 301 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 302 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 303 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 304 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 305 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 306 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 307 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 308 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 309 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 310 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 311 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 312 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 313 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 314 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 315 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 316 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 317 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 318 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 319 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 320 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 321 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 322 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 323 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 324 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 325 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 326 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 327 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 328 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 329 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 330 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 331 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 332 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 333 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 334 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 335 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 336 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 337 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 338 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 339 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 340 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 341 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 342 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 343 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 344 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 345 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 346 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 347 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 348 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 349 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 350 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 351 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 352 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 353 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 354 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 355 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 356 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 357 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 358 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 359 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 360 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 361 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 362 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 363 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 364 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 365 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 366 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 367 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 368 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 369 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 370 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 371 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 372 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 373 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 374 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 375 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 376 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 377 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 378 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 379 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 380 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 381 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 382 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 383 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 384 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 385 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 386 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 387 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 388 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 389 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 390 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 391 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 392 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 393 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 394 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 395 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 396 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 397 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 398 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 399 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 400 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 401 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 402 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 403 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 404 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 405 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 406 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 407 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 408 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 409 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 410 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 411 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 412 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 413 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 414 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 415 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 416 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 417 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 418 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 419 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 420 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 421 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 422 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 423 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 424 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 425 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 426 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 427 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 428 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 429 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 430 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 431 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 432 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 433 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 434 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 435 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 436 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 437 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 438 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 439 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 440 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 441 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 442 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 443 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 444 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 445 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 446 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 447 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 448 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 449 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 450 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 451 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 452 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 453 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 454 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 455 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 456 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 457 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 458 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 459 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 460 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 461 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 462 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 463 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 464 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 465 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 466 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 467 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 468 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 469 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 470 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 471 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 472 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 473 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 474 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 475 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 476 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 477 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 478 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 479 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 480 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 481 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 482 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 483 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 484 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 485 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 486 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 487 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 488 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 489 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 490 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 491 were received 2 bytes was expected 1
	solution_test.go:832: From url with index 492 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 493 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 494 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 495 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 496 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 497 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 498 were received 0 bytes was expected 1
	solution_test.go:832: From url with index 499 were received 0 bytes was expected 1
FAIL
exit status 1
FAIL	_/tmp/d20170109-30451-11e94cp	0.075s
--- FAIL: TestSlowLingchiWithMaxConnections (0.53s)
	solution_test.go:902: Expected to read 100 bytes from simple download but got 1
	solution_test.go:53: Expected result was '5468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d6f73742065706963206f662061' but got '54'
	solution_test.go:913: From url with index 0 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 1 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 2 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 3 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 4 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 5 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 6 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 7 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 8 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 9 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 10 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 11 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 12 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 13 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 14 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 15 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 16 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 17 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 18 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 19 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 20 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 21 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 22 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 23 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 24 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 25 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 26 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 27 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 28 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 29 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 30 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 31 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 32 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 33 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 34 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 35 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 36 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 37 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 38 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 39 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 40 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 41 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 42 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 43 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 44 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 45 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 46 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 47 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 48 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 49 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 50 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 51 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 52 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 53 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 54 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 55 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 56 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 57 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 58 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 59 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 60 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 61 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 62 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 63 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 64 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 65 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 66 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 67 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 68 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 69 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 70 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 71 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 72 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 73 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 74 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 75 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 76 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 77 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 78 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 79 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 80 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 81 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 82 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 83 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 84 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 85 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 86 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 87 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 88 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 89 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 90 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 91 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 92 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 93 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 94 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 95 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 96 were received 2 bytes was expected 1
	solution_test.go:913: From url with index 97 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 98 were received 0 bytes was expected 1
	solution_test.go:913: From url with index 99 were received 2 bytes was expected 1
FAIL
exit status 1
FAIL	_/tmp/d20170109-30451-11e94cp	0.535s
--- FAIL: TestSlowLingchiWithBothMaxConnectionsAndALotOfErrors (0.28s)
	solution_test.go:1000: Expected to read 50 bytes from simple download but got 1
	solution_test.go:53: Expected result was '5468697320495320746865206d6f73742065706963206f6620616c6c20726573706f6e73655468697320495320746865206d' but got '54'
FAIL
exit status 1
FAIL	_/tmp/d20170109-30451-11e94cp	0.289s

История (1 версия и 1 коментар)

Константин обнови решението на 03.01.2017 01:25 (преди над 1 година)

+package main
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+)
+
+var noValidUrls = "no valid urls"
+
+func getFileLengthFromURL(url string) int {
+ res, err := http.Head(url)
+ if err != nil {
+ return 0
+ }
+
+ contentLength, err := strconv.Atoi(res.Header.Get("Content-Length"))
+ if err != nil {
+ return 0
+ }
+
+ return contentLength
+}
+
+func getBytesEnd(r Reader) int {
+ if len(r.urls)-len(r.invalidUrls) == 1 {
+ return r.fileBytesCount - 1
+ }
+
+ if r.fileBytesCount > 0 && r.readIndex+1 > r.fileBytesCount-1 {
+ return r.fileBytesCount - 1
+ }
+
+ return r.readIndex + 1
+}
+
+func contains(s []string, e string) bool {
+ for _, a := range s {
+ if a == e {
+ return true
+ }
+ }
+ return false
+}
+
+func getUrlWithLowestBytesRead(r Reader) string {
+ var minBytesRead = 0
+ var minURL = ""
+
+ for url, bytesRead := range r.urls {
+ if !contains(r.invalidUrls, url) && bytesRead == 0 {
+ return url
+ } else if !contains(r.invalidUrls, url) && (minBytesRead > bytesRead || minBytesRead == 0) {
+ minBytesRead = bytesRead
+ minURL = url
+ }
+ }
+
+ return minURL
+}
+
+type Reader struct {
+ data []byte
+ readIndex int
+ urls map[string]int
+ invalidUrls []string
+ fileBytesCount int
+ calledServer bool
+}
+
+func CreateReader(urls []string) io.Reader {
+ var reader = new(Reader)
+ reader.urls = make(map[string]int)
+ for _, url := range urls {
+ reader.urls[url] = 0
+ }
+ reader.fileBytesCount = -1
+ reader.calledServer = false
+ reader.invalidUrls = []string{}
+ return reader
+}
+
+func (r *Reader) Read(p []byte) (int, error) {
+ if r.urls == nil || r.fileBytesCount == 0 {
+ return 0, errors.New("error")
+ }
+
+ if r.calledServer && r.readIndex > r.fileBytesCount-1 {
+ return 0, io.EOF
+ }
+
+ var bytesRead, err = r.readFromUrls()
+ if err != nil {
+ if bytesRead > 0 {
+ copy(p, r.data[r.readIndex-bytesRead:])
+ }
+ if len(r.urls)-len(r.invalidUrls) == 0 {
+ return bytesRead, errors.New(noValidUrls)
+ }
+ return bytesRead, err
+ }
+
+ var n = copy(p, r.data[r.readIndex-bytesRead:])
+ return n, nil
+}
+
+func (r *Reader) readFromUrls() (int, error) {
+ var bytesRead int
+
+ var url = getUrlWithLowestBytesRead(*r)
+
+ if !r.calledServer {
+ r.fileBytesCount = getFileLengthFromURL(url)
+ r.calledServer = true
+ }
+
+ for url != "" {
+ if !contains(r.invalidUrls, url) && r.readIndex < r.fileBytesCount {
+ contents, contentLength, err := r.readFromUrl(url)
+ if contents != nil && len(contents) > 0 {
+ var trimmedContents = contents[0:contentLength]
+ r.data = append(r.data, trimmedContents...)
+ r.readIndex = r.readIndex + contentLength
+ bytesRead = bytesRead + contentLength
+ r.urls[url] = r.urls[url] + contentLength
+ }
+
+ if err != nil {
+ return bytesRead, err
+ }
+ }
+
+ if r.readIndex >= r.fileBytesCount {
+ return bytesRead, nil
+ }
+
+ url = getUrlWithLowestBytesRead(*r)
+ }
+ return bytesRead, nil
+}
+
+func (r *Reader) readFromUrl(url string) ([]byte, int, error) {
+ var contents = []byte{}
+ var contentLength = 0
+
+ var bytesEnd = getBytesEnd(*r)
+ var bytesStart = r.readIndex
+
+ for len(contents) == 0 {
+ client := &http.Client{}
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, 0, err
+ }
+ var rangeHeader = fmt.Sprintf("bytes=%d-%d", bytesStart, bytesEnd)
+ req.Header.Add("Range", rangeHeader)
+ res, err := client.Do(req)
+
+ if err != nil {
+ return nil, 0, err
+ }
+
+ if res != nil && res.StatusCode >= 400 {
+ r.invalidUrls = append(r.invalidUrls, []string{url}...)
+ return nil, 0, nil
+ }
+
+ contents, err = ioutil.ReadAll(res.Body)
+ if err != nil {
+ r.invalidUrls = append(r.invalidUrls, []string{url}...)
+ return contents, len(contents), err
+ }
+
+ if len(contents) > 0 {
+ res.Body.Close()
+ }
+
+ contentLength, err = strconv.Atoi(res.Header.Get("Content-Length"))
+ if err != nil {
+ return nil, 0, err
+ }
+ }
+
+ return contents, contentLength, nil
+}
+
+func DownloadFile(ctx context.Context, urls []string) io.Reader {
+ var reader = CreateReader(urls)
+ return reader
+}