func (req *Request) WriteTo(w io.Writer) (int64, error) {
	return writeBufio(req, w)
}
WriteTo writes request to w. It implements io.WriterTo.
package fasthttp
import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"mime/multipart"
	"os"
	"sync"
)
type Request struct {
	noCopy noCopy
	Header RequestHeader
	body []byte
	w    requestBodyWriter
	bodyStream io.Reader
	uri      URI
	postArgs Args
	multipartForm         *multipart.Form
	multipartFormBoundary string
	parsedURI      bool
	parsedPostArgs bool
}
type Response struct {
	noCopy noCopy
	Header ResponseHeader
	body []byte
	w    responseBodyWriter
	bodyStream io.Reader
	SkipBody bool
}
func (req *Request) SetRequestURI(requestURI string) {
	req.Header.SetRequestURI(requestURI)
	req.parsedURI = false
}
func (req *Request) SetRequestURIBytes(requestURI []byte) {
	req.Header.SetRequestURIBytes(requestURI)
	req.parsedURI = false
}
func (req *Request) RequestURI() []byte {
	if req.parsedURI {
		requestURI := req.uri.RequestURI()
		req.SetRequestURIBytes(requestURI)
	}
	return req.Header.RequestURI()
}
func (resp *Response) StatusCode() int {
	return resp.Header.StatusCode()
}
func (resp *Response) SetStatusCode(statusCode int) {
	resp.Header.SetStatusCode(statusCode)
}
func (resp *Response) ConnectionClose() bool {
	return resp.Header.ConnectionClose()
}
func (resp *Response) SetConnectionClose() {
	resp.Header.SetConnectionClose()
}
func (req *Request) ConnectionClose() bool {
	return req.Header.ConnectionClose()
}
func (req *Request) SetConnectionClose() {
	req.Header.SetConnectionClose()
}
func (resp *Response) SendFile(path string) error {
	f, err := os.Open(path)
	if err != nil {
		return err
	}
	fileInfo, err := f.Stat()
	if err != nil {
		f.Close()
		return err
	}
	size64 := fileInfo.Size()
	size := int(size64)
	if int64(size) != size64 {
		size = -1
	}
	resp.Header.SetLastModified(fileInfo.ModTime())
	resp.SetBodyStream(f, size)
	return nil
}
func (req *Request) SetBodyStream(bodyStream io.Reader, bodySize int) {
	req.ResetBody()
	req.bodyStream = bodyStream
	req.Header.SetContentLength(bodySize)
}
func (resp *Response) SetBodyStream(bodyStream io.Reader, bodySize int) {
	resp.ResetBody()
	resp.bodyStream = bodyStream
	resp.Header.SetContentLength(bodySize)
}
func (req *Request) SetBodyStreamWriter(sw StreamWriter) {
	sr := NewStreamReader(sw)
	req.SetBodyStream(sr, -1)
}
func (resp *Response) SetBodyStreamWriter(sw StreamWriter) {
	sr := NewStreamReader(sw)
	resp.SetBodyStream(sr, -1)
}
func (resp *Response) BodyWriter() io.Writer {
	resp.w.r = resp
	return &resp.w
}
func (req *Request) BodyWriter() io.Writer {
	req.w.r = req
	return &req.w
}
type responseBodyWriter struct {
	r *Response
}
func (w *responseBodyWriter) Write(p []byte) (int, error) {
	w.r.AppendBody(p)
	return len(p), nil
}
type requestBodyWriter struct {
	r *Request
}
func (w *requestBodyWriter) Write(p []byte) (int, error) {
	w.r.AppendBody(p)
	return len(p), nil
}
func (resp *Response) Body() []byte {
	if resp.bodyStream != nil {
		var w ByteBuffer
		_, err := copyZeroAlloc(&w, resp.bodyStream)
		resp.closeBodyStream()
		if err != nil {
			resp.body = append(resp.body[:0], err.Error()...)
		} else {
			resp.body = append(resp.body[:0], w.B...)
		}
	}
	return resp.body
}
func (req *Request) BodyGunzip() ([]byte, error) {
	return gunzipData(req.Body())
}
func (resp *Response) BodyGunzip() ([]byte, error) {
	return gunzipData(resp.Body())
}
func gunzipData(p []byte) ([]byte, error) {
	var bb ByteBuffer
	_, err := WriteGunzip(&bb, p)
	if err != nil {
		return nil, err
	}
	return bb.B, nil
}
func (req *Request) BodyInflate() ([]byte, error) {
	return inflateData(req.Body())
}
func (resp *Response) BodyInflate() ([]byte, error) {
	return inflateData(resp.Body())
}
func inflateData(p []byte) ([]byte, error) {
	var bb ByteBuffer
	_, err := WriteInflate(&bb, p)
	if err != nil {
		return nil, err
	}
	return bb.B, nil
}
func (req *Request) BodyWriteTo(w io.Writer) error {
	if req.bodyStream != nil {
		_, err := copyZeroAlloc(w, req.bodyStream)
		req.closeBodyStream()
		return err
	}
	if req.onlyMultipartForm() {
		return WriteMultipartForm(w, req.multipartForm, req.multipartFormBoundary)
	}
	_, err := w.Write(req.body)
	return err
}
func (resp *Response) BodyWriteTo(w io.Writer) error {
	if resp.bodyStream != nil {
		_, err := copyZeroAlloc(w, resp.bodyStream)
		resp.closeBodyStream()
		return err
	}
	_, err := w.Write(resp.body)
	return err
}
func (resp *Response) AppendBody(p []byte) {
	resp.closeBodyStream()
	resp.body = append(resp.body, p...)
}
func (resp *Response) AppendBodyString(s string) {
	resp.closeBodyStream()
	resp.body = append(resp.body, s...)
}
func (resp *Response) SetBody(body []byte) {
	resp.closeBodyStream()
	resp.body = append(resp.body[:0], body...)
}
func (resp *Response) SetBodyString(body string) {
	resp.closeBodyStream()
	resp.body = append(resp.body[:0], body...)
}
func (resp *Response) ResetBody() {
	resp.closeBodyStream()
	resp.body = resp.body[:0]
}
func (req *Request) Body() []byte {
	if req.bodyStream != nil {
		var w ByteBuffer
		_, err := copyZeroAlloc(&w, req.bodyStream)
		req.closeBodyStream()
		if err != nil {
			req.body = append(req.body[:0], err.Error()...)
		} else {
			req.body = append(req.body[:0], w.B...)
		}
	} else if req.onlyMultipartForm() {
		body, err := marshalMultipartForm(req.multipartForm, req.multipartFormBoundary)
		if err != nil {
			return []byte(err.Error())
		}
		return body
	}
	return req.body
}
func (req *Request) AppendBody(p []byte) {
	req.RemoveMultipartFormFiles()
	req.closeBodyStream()
	req.body = append(req.body, p...)
}
func (req *Request) AppendBodyString(s string) {
	req.RemoveMultipartFormFiles()
	req.closeBodyStream()
	req.body = append(req.body, s...)
}
func (req *Request) SetBody(body []byte) {
	req.RemoveMultipartFormFiles()
	req.closeBodyStream()
	req.body = append(req.body[:0], body...)
}
func (req *Request) SetBodyString(body string) {
	req.RemoveMultipartFormFiles()
	req.closeBodyStream()
	req.body = append(req.body[:0], body...)
}
func (req *Request) ResetBody() {
	req.RemoveMultipartFormFiles()
	req.closeBodyStream()
	req.body = req.body[:0]
}
func (req *Request) CopyTo(dst *Request) {
	req.copyToSkipBody(dst)
	dst.body = append(dst.body[:0], req.body...)
}
func (req *Request) copyToSkipBody(dst *Request) {
	dst.Reset()
	req.Header.CopyTo(&dst.Header)
	req.uri.CopyTo(&dst.uri)
	dst.parsedURI = req.parsedURI
	req.postArgs.CopyTo(&dst.postArgs)
	dst.parsedPostArgs = req.parsedPostArgs
}
func (resp *Response) CopyTo(dst *Response) {
	resp.copyToSkipBody(dst)
	dst.body = append(dst.body[:0], resp.body...)
}
func (resp *Response) copyToSkipBody(dst *Response) {
	dst.Reset()
	resp.Header.CopyTo(&dst.Header)
	dst.SkipBody = resp.SkipBody
}
func swapRequestBody(a, b *Request) {
	a.body, b.body = b.body, a.body
	a.bodyStream, b.bodyStream = b.bodyStream, a.bodyStream
}
func swapResponseBody(a, b *Response) {
	a.body, b.body = b.body, a.body
	a.bodyStream, b.bodyStream = b.bodyStream, a.bodyStream
}
func (req *Request) URI() *URI {
	req.parseURI()
	return &req.uri
}
func (req *Request) parseURI() {
	if req.parsedURI {
		return
	}
	req.parsedURI = true
	req.uri.parseQuick(req.Header.RequestURI(), &req.Header)
}
func (req *Request) PostArgs() *Args {
	req.parsePostArgs()
	return &req.postArgs
}
func (req *Request) parsePostArgs() {
	if req.parsedPostArgs {
		return
	}
	req.parsedPostArgs = true
	if !bytes.Equal(req.Header.ContentType(), strPostArgsContentType) {
		return
	}
	req.postArgs.ParseBytes(req.body)
	return
}
var ErrNoMultipartForm = errors.New("request has no multipart/form-data Content-Type")
func (req *Request) MultipartForm() (*multipart.Form, error) {
	if req.multipartForm != nil {
		return req.multipartForm, nil
	}
	req.multipartFormBoundary = string(req.Header.MultipartFormBoundary())
	if len(req.multipartFormBoundary) == 0 {
		return nil, ErrNoMultipartForm
	}
	ce := req.Header.peek(strContentEncoding)
	body := req.body
	if bytes.Equal(ce, strGzip) {
		var err error
		if body, err = AppendGunzipBytes(nil, body); err != nil {
			return nil, fmt.Errorf("cannot gunzip request body: %s", err)
		}
	} else if len(ce) > 0 {
		return nil, fmt.Errorf("unsupported Content-Encoding: %q", ce)
	}
	f, err := readMultipartForm(bytes.NewReader(body), req.multipartFormBoundary, len(body), len(body))
	if err != nil {
		return nil, err
	}
	req.multipartForm = f
	return f, nil
}
func marshalMultipartForm(f *multipart.Form, boundary string) ([]byte, error) {
	var buf ByteBuffer
	if err := WriteMultipartForm(&buf, f, boundary); err != nil {
		return nil, err
	}
	return buf.B, nil
}
func WriteMultipartForm(w io.Writer, f *multipart.Form, boundary string) error {
	if len(boundary) == 0 {
		panic("BUG: form boundary cannot be empty")
	}
	mw := multipart.NewWriter(w)
	if err := mw.SetBoundary(boundary); err != nil {
		return fmt.Errorf("cannot use form boundary %q: %s", boundary, err)
	}
	for k, vv := range f.Value {
		for _, v := range vv {
			if err := mw.WriteField(k, v); err != nil {
				return fmt.Errorf("cannot write form field %q value %q: %s", k, v, err)
			}
		}
	}
	for k, fvv := range f.File {
		for _, fv := range fvv {
			vw, err := mw.CreateFormFile(k, fv.Filename)
			if err != nil {
				return fmt.Errorf("cannot create form file %q (%q): %s", k, fv.Filename, err)
			}
			fh, err := fv.Open()
			if err != nil {
				return fmt.Errorf("cannot open form file %q (%q): %s", k, fv.Filename, err)
			}
			if _, err = copyZeroAlloc(vw, fh); err != nil {
				return fmt.Errorf("error when copying form file %q (%q): %s", k, fv.Filename, err)
			}
			if err = fh.Close(); err != nil {
				return fmt.Errorf("cannot close form file %q (%q): %s", k, fv.Filename, err)
			}
		}
	}
	if err := mw.Close(); err != nil {
		return fmt.Errorf("error when closing multipart form writer: %s", err)
	}
	return nil
}
func readMultipartForm(r io.Reader, boundary string, size, maxInMemoryFileSize int) (*multipart.Form, error) {
	if size <= 0 {
		panic(fmt.Sprintf("BUG: form size must be greater than 0. Given %d", size))
	}
	lr := io.LimitReader(r, int64(size))
	mr := multipart.NewReader(lr, boundary)
	f, err := mr.ReadForm(int64(maxInMemoryFileSize))
	if err != nil {
		return nil, fmt.Errorf("cannot read multipart/form-data body: %s", err)
	}
	return f, nil
}
func (req *Request) Reset() {
	req.Header.Reset()
	req.resetSkipHeader()
}
func (req *Request) resetSkipHeader() {
	req.closeBodyStream()
	req.body = reuseBody(req.body)
	req.uri.Reset()
	req.parsedURI = false
	req.postArgs.Reset()
	req.parsedPostArgs = false
	req.RemoveMultipartFormFiles()
}
func (req *Request) RemoveMultipartFormFiles() {
	if req.multipartForm != nil {
		req.multipartForm.RemoveAll()
		req.multipartForm = nil
	}
	req.multipartFormBoundary = ""
}
func (resp *Response) Reset() {
	resp.Header.Reset()
	resp.resetSkipHeader()
	resp.SkipBody = false
}
func (resp *Response) resetSkipHeader() {
	resp.closeBodyStream()
	resp.body = reuseBody(resp.body)
}
func reuseBody(body []byte) []byte {
	return body[:0]
}
func (req *Request) Read(r *bufio.Reader) error {
	return req.ReadLimitBody(r, 0)
}
const defaultMaxInMemoryFileSize = 16 * 1024 * 1024
var errGetOnly = errors.New("non-GET request received")
func (req *Request) ReadLimitBody(r *bufio.Reader, maxBodySize int) error {
	return req.readLimitBody(r, maxBodySize, false)
}
func (req *Request) readLimitBody(r *bufio.Reader, maxBodySize int, getOnly bool) error {
	req.resetSkipHeader()
	err := req.Header.Read(r)
	if err != nil {
		return err
	}
	if getOnly && !req.Header.IsGet() {
		return errGetOnly
	}
	if req.Header.noBody() {
		return nil
	}
	if req.MayContinue() {
		return nil
	}
	return req.ContinueReadBody(r, maxBodySize)
}
func (req *Request) MayContinue() bool {
	return bytes.Equal(req.Header.peek(strExpect), str100Continue)
}
func (req *Request) ContinueReadBody(r *bufio.Reader, maxBodySize int) error {
	var err error
	contentLength := req.Header.ContentLength()
	if contentLength > 0 {
		if maxBodySize > 0 && contentLength > maxBodySize {
			return ErrBodyTooLarge
		}
		req.multipartFormBoundary = string(req.Header.MultipartFormBoundary())
		if len(req.multipartFormBoundary) > 0 && len(req.Header.peek(strContentEncoding)) == 0 {
			req.multipartForm, err = readMultipartForm(r, req.multipartFormBoundary, contentLength, defaultMaxInMemoryFileSize)
			if err != nil {
				req.Reset()
			}
			return err
		}
	}
	if contentLength == -2 {
		req.Header.SetContentLength(0)
		return nil
	}
	req.body, err = readBody(r, contentLength, maxBodySize, req.body)
	if err != nil {
		req.Reset()
		return err
	}
	req.Header.SetContentLength(len(req.body))
	return nil
}
func (resp *Response) Read(r *bufio.Reader) error {
	return resp.ReadLimitBody(r, 0)
}
func (resp *Response) ReadLimitBody(r *bufio.Reader, maxBodySize int) error {
	resp.resetSkipHeader()
	err := resp.Header.Read(r)
	if err != nil {
		return err
	}
	if resp.Header.StatusCode() == StatusContinue {
		if err = resp.Header.Read(r); err != nil {
			return err
		}
	}
	if !resp.mustSkipBody() {
		resp.body, err = readBody(r, resp.Header.ContentLength(), maxBodySize, resp.body)
		if err != nil {
			resp.Reset()
			return err
		}
		resp.Header.SetContentLength(len(resp.body))
	}
	return nil
}
func (resp *Response) mustSkipBody() bool {
	return resp.SkipBody || resp.Header.mustSkipContentLength()
}
var errRequestHostRequired = errors.New("missing required Host header in request")