Этот вопрос закрыт для ответов, так как повторяет вопрос Как принудительно закрыть соединение без ожидания полного ответа запроса?
@t38c3j

Как принудительно закрыть соединение без ожидания полного ответа запроса?

Есть программа на python для скачивания только части файла из ответа запроса, aiohttp автоматически закрывает соединение после выхода из контекста без ожидания получения полного ответа от сервера, то есть, если файл весит 1GB a мы прочитали например только 50MB по необходимости, то оставшееся мы не будем гонять по сети (проверено мониторингом сети)
Код на python

async with c.get(...) as resp:
    if resp.status != 200:
        raise Exception(...)
    if int.from_bytes(await resp.content.read(4), 'little') != 288633362:
        raise Exception(...)
    if int.from_bytes(await resp.content.read(4), 'little') != 2:
        raise Exception(...)
    async with aiofiles.open(...) as f:
        block_length = int.from_bytes(await resp.content.read(4), 'little')
        await f.write(await resp.content.read(block_length))
        await f.write(b'\n')
        block_length = int.from_bytes(await resp.content.read(4), 'little')
        await f.write(await resp.content.read(block_length))


Пытаюсь повторить данное поведение в го с использованием net/http
Код на go

func verifySignature(r io.Reader) error {
	var s uint32
	if err := binary.Read(r, binary.LittleEndian, &s); err != nil {
		return ...
	}
	if s != 288633362 {
		return ...
	}
	return nil
}

func validateBlockCount(r io.Reader) error {
	var c uint32
	if err := binary.Read(r, binary.LittleEndian, &c); err != nil {
		return ...
	}
	if c != 2 {
		return ...
	}
	return nil
}

func parseBlock(r io.Reader) ([]byte, error) {
	var l uint32
	if err := binary.Read(r, binary.LittleEndian, &l); err != nil {
		return nil, ...
	}
	d := make([]byte, l)
	if err := binary.Read(r, binary.LittleEndian, &d); err != nil {
		return nil, ...
	}
	return d, nil
}

func download(...) {
	req, err := http.NewRequest(...)
	if err != nil {
		return ...
	}
	resp, err := c.Do(req)
	if err != nil {
		return ...

	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return ...
	}
	r := bufio.NewReader(resp.Body)
	if err := verifySignature(r); err != nil {
		return ...
	}
	if err := validateBlockCount(r); err != nil {
		return ...
	}
	..., err = parseBlock(r)
	if err != nil {
		return ...
	}
	..., err = parseBlock(r)
	if err != nil {
		return ...
}

}

  • Вопрос задан
  • 68 просмотров
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы