public static function transfer($socket, $request, $method)
    {
        if (!is_resource($socket)) {
            throw new ClientException('Invalid socket used');
        }

        assert(is_string($request));

        @fwrite($socket, $request);
        @fflush($socket);

        $contentLength    = null;
        $expectedLength   = null;
        $totalRead        = 0;
        $contentLengthPos = 0;

        $result = '';
        $first  = true;

        while ($first || !feof($socket)) {
            $read = @fread($socket, self::CHUNK_SIZE);
            if ($read === false || $read === '') {
                break;
            }

            $totalRead += strlen($read);

            if ($first) {
                $result = $read;
                $first  = false;
            } else {
                $result .= $read;
            }

            if ($contentLength === null) {
                // check if content-length header is present

                // 12 = minimum offset (i.e. strlen("HTTP/1.1 xxx") -
                // after that we could see "content-length:"
                $pos = stripos($result, 'content-length: ', 12);

                if ($pos !== false) {
                    $contentLength    = (int) substr($result, $pos + 16, 10); // 16 = strlen("content-length: ")
                    $contentLengthPos = $pos + 17; // 17 = 16 + 1 one digit

                    if ($method === 'HEAD') {
                        // for HTTP HEAD requests, the server will respond
                        // with the proper Content-Length value, but will
                        // NOT return the body.
                        $contentLength = 0;
                    }
                }
            }

            if ($contentLength !== null && $expectedLength === null) {
                $bodyStart = strpos($result, "\r\n\r\n", $contentLengthPos);
                if ($bodyStart !== false) {
                    $bodyStart += 4; // 4 = strlen("\r\n\r\n")
                    $expectedLength = $bodyStart + $contentLength;
                }
            }

            if ($expectedLength !== null && $totalRead >= $expectedLength) {
                break;
            }
        }

        return $result;
    }