Make HTTP(S) request.
			headers can be either dict or callable(url, method, body, mimetype or None).
			decode (response body) = None | json.
			encode (data) = None | json | form | files.

def request( self, url, method='get',
			decode=None, encode=None, data=None,
			headers=None, raise_for=dict(), queue_lines=None ):
		'''Make HTTP(S) request.
			headers can be either dict or callable(url, method, body, mimetype or None).
			decode (response body) = None | json.
			encode (data) = None | json | form | files.'''
		if self.debug_requests:
			url_debug = _dump_trunc(url)
			log.debug('HTTP request: {} {} (h: {}, enc: {}, dec: {}, data: {!r})'.format(
				method, url_debug, headers, encode, decode, _dump_trunc(data) ))

		timeout = HTTPTimeout(**self.request_io_timeouts)
		req_headers = {'User-Agent': 'txU1'}

		if data is not None:
			if encode == 'files':
				boundary = os.urandom(16).encode('hex')
				req_headers['Content-Type'] = 'multipart/form-data; boundary={}'.format(boundary)
				data = MultipartDataSender(data, boundary)
				if not callable(headers): yield data.calculate_length()
				else:
					body = io.BytesIO()
					yield data.calculate_length(body)
					headers = headers(url, method, body.getvalue(), 'multipart/form-data')
			else:
				if encode is None:
					if isinstance(data, types.StringTypes): data = io.BytesIO(data)
				elif encode == 'form':
					req_headers['Content-Type'] = 'application/x-www-form-urlencoded'
					data = io.BytesIO(urllib.urlencode(data))
				elif encode == 'json':
					req_headers['Content-Type'] = 'application/json'
					data = io.BytesIO(json.dumps(data))
				else: raise ValueError('Unknown request encoding: {}'.format(encode))
				if callable(headers):
					data.seek(0)
					headers = headers(url, method, data.read(), req_headers.get('Content-Type'))
				data = FileBodyProducer(data)
		elif callable(headers): headers = headers(url, method, '', None)

		# Passed "headers" should be allowed to be modified by body_hash()
		for k, v in (headers or dict()).viewitems():
			req_headers[force_bytes(k)] = force_bytes(v)
		url, method = it.imap(force_bytes, [url, method.lower()])

		if decode == 'json': req_headers.setdefault('Accept', 'application/json')
		elif decode is not None:
			raise ValueError('Unknown response decoding method: {}'.format(decode))

		res_deferred = first_result( timeout,
			self.request_agent.request( method.upper(), url,
				Headers(dict((k,[v]) for k,v in req_headers.viewitems())), data ) )
		code = res_body = None
		try:
			res = yield res_deferred
			code = res.code
			if code == http.NO_CONTENT: defer.returnValue(None)
			if code not in [http.OK, http.CREATED]:
				if self.debug_requests:
					res_body = defer.Deferred()
					res.deliverBody(DataReceiver(res_body, timer=timeout, allow_loss=True))
					res_body = yield first_result(timeout, res_body)
					log.debug('HTTP error response body: {!r}'.format(res_body))
				raise ProtocolError(code, res.phrase)

			res_body = defer.Deferred()
			res.deliverBody(DataReceiver(res_body, timer=timeout))
			res_body = yield first_result(timeout, res_body)

			if self.debug_requests:
				log.debug( 'HTTP request done ({} {}): {} {} {}, body_len: {}'\
					.format(method, url_debug, code, res.phrase, res.version, len(res_body)) )
			defer.returnValue(json.loads(res_body) if decode is not None else res_body)

		except ( timeout.ActivityTimeout, TimeoutError,
				ResponseFailed, RequestNotSent, RequestTransmissionFailed ) as err:
			if isinstance(err, timeout.ActivityTimeout):
				if not res_deferred.called: res_deferred.cancel()
				if res_body and not res_body.called: res_body.cancel()
			if self.debug_requests:
				log.debug(
					'HTTP transport (underlying protocol) error ({} {}): {}'\
					.format(method, url_debug, err.message or repr(err.args)) )
			raise UnderlyingProtocolError(err)

		except ProtocolError as err:
			if self.debug_requests:
				log.debug(
					'HTTP request handling error ({} {}, code: {}): {}'\
					.format(method, url_debug, code, err.message) )
			raise raise_for.get(code, ProtocolError)(code, err.message)

		except RequestGenerationFailed as err:
			err[0][0].raiseException()

		finally: timeout.state_finished()