def _handle_header_ex(stream, line, handle_done): ''' Handles the HEADER_EX event ''' context = stream.opaque line = line.rstrip() if not line: logging.debug('<') handle_done(stream) return logging.debug('< %s', six.bytes_to_string_safe(line, 'utf-8')) # Note: must preceed header parsing to permit colons in folded line(s) if context.last_hdr and line[0:1] in (SPACE, TAB): value = context.headers[context.last_hdr] value += SPACE value += line.strip() # Note: make sure there are no leading or trailing spaces context.headers[context.last_hdr] = value.strip() return index = line.find(COLON) if index >= 0: name, value = line.split(COLON, 1) name = name.strip().lower() value = value.strip() if name not in context.headers: context.headers[name] = value else: # # "Multiple message-header fields with the same field-name MAY # be present in a message if and only if the entire field-value # for that header field is defined as a comma-separated list # [i.e., #(values)]. It MUST be possible to combine the multiple # header fields into one "field-name: field-value" pair, without # changing the semantics of the message, by appending each # subsequent field-value to the first, each separated by # a comma." (RFC2616, sect. 4.2) # context.headers[name] += COMMASPACE context.headers[name] += value context.last_hdr = name return # # N.B. I have observed that this error is often triggered when one # overrides handle_end_of_body() and forgets to invoke the parent class # method, which resets the line reader. # raise RuntimeError('http_clnt: internal error #2')
def _handle_firstline(self, stream, line): ''' Handles the FIRSTLINE event ''' context = stream.opaque line = line.rstrip() logging.debug('< %s', six.bytes_to_string_safe(line, 'utf-8')) vector = line.split(None, 2) if len(vector) != 3: raise RuntimeError('http_clnt: invalid first line') context.protocol = vector[0] if not context.protocol.startswith(HTTP_PREFIX): raise RuntimeError('http_clnt: invalid protocol') if context.protocol not in (HTTP11, HTTP10): raise RuntimeError('http_clnt: unsuppored protocol') context.code = vector[1] context.reason = vector[2] context.last_hdr = EMPTY_STRING context.headers = {} context.handle_line = self._handle_header