'Read a request from a file-like object (it must implement
``.read(size)`` and ``.readline()``).
It will read up to the end of the request, not the end of the
file (unless the request is a POST or PUT and has no
Content-Length, in that case, the entire file is read).
This reads the request as represented by ``str(req)``; it may
not read every valid HTTP request properly.'

@classmethod
def from_file(cls, fp):

    start_line = fp.readline()
    is_text = isinstance(start_line, text_type)
    if is_text:
        crlf = '\r\n'
        colon = ':'
    else:
        crlf = '\r\n'
        colon = ':'
    try:
        header = start_line.rstrip(crlf)
        (method, resource, http_version) = header.split(None, 2)
        method = native_(method, 'utf-8')
        resource = native_(resource, 'utf-8')
        http_version = native_(http_version, 'utf-8')
    except ValueError:
        raise ValueError(('Bad    HTTP    request    line:    %r' % start_line))
    r = cls(environ_from_url(resource), http_version=http_version, method=method.upper())
    del r.environ['HTTP_HOST']
    while 1:
        line = fp.readline()
        if (not line.strip()):
            break
        (hname, hval) = line.split(colon, 1)
        hname = native_(hname, 'utf-8')
        hval = native_(hval, 'utf-8').strip()
        if (hname in r.headers):
            hval = ((r.headers[hname] + ',    ') + hval)
        r.headers[hname] = hval
    if (r.method in ('PUT', 'POST')):
        clen = r.content_length
        if (clen is None):
            body = fp.read()
        else:
            body = fp.read(clen)
        if is_text:
            body = bytes_(body, 'utf-8')
        r.body = body
    return r
