Beispiel #1
0
// RoundTrip implements http.RoundTripper.RoundTrip.
func (binder Binder) RoundTrip(req *http.Request) (*http.Response, error) {
	if req.Proto == "" {
		req.Proto = fmt.Sprintf("HTTP/%d.%d", req.ProtoMajor, req.ProtoMinor)
	}

	if req.Body != nil {
		if req.ContentLength == -1 {
			req.TransferEncoding = []string{"chunked"}
		}
	} else {
		req.Body = ioutil.NopCloser(bytes.NewReader(nil))
	}

	recorder := httptest.NewRecorder()

	binder.handler.ServeHTTP(recorder, req)

	resp := http.Response{
		Request:    req,
		StatusCode: recorder.Code,
		Status:     http.StatusText(recorder.Code),
		Header:     recorder.HeaderMap,
	}

	if recorder.Flushed {
		resp.TransferEncoding = []string{"chunked"}
	}

	if recorder.Body != nil {
		resp.Body = ioutil.NopCloser(recorder.Body)
	}

	return &resp, nil
}
Beispiel #2
0
func post(url_ string, oauthHeaders map[string]string) (r *http.Response, err error) {
	var req http.Request
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	req.Header = map[string][]string{
		"Authorization": {"OAuth "},
	}
	req.TransferEncoding = []string{"chunked"}

	first := true
	for k, v := range oauthHeaders {
		if first {
			first = false
		} else {
			req.Header["Authorization"][0] += ",\n    "
		}
		req.Header["Authorization"][0] += k + "=\"" + v + "\""
	}

	req.URL, err = url.Parse(url_)
	if err != nil {
		return nil, err
	}

	return send(&req)
}
Beispiel #3
0
func (c *Client) newRequest(method, apiPath string, options *RequestOptions) (*http.Request, error) {
	if c.client == nil {
		return nil, errors.New("Client has not been authenticated")
	}

	urlPath := path.Join("api", apiVersion, apiPath)
	if options != nil && options.QueryParams != nil && len(*options.QueryParams) > 0 {
		urlPath = urlPath + "?" + options.QueryParams.Encode()
	}
	rel, err := url.Parse(urlPath)
	if err != nil {
		return nil, err
	}

	u := c.BaseUrl.ResolveReference(rel)

	buf := new(bytes.Buffer)

	if options != nil && options.JsonBody != nil {
		err := json.NewEncoder(buf).Encode(options.JsonBody)
		if err != nil {
			return nil, err
		}
	}

	var req *http.Request

	if options != nil && options.RawBody != nil {
		req, err = http.NewRequest(method, u.String(), options.RawBody)
		req.ContentLength = options.RawBodyLength
	} else {
		req, err = http.NewRequest(method, u.String(), buf)
	}
	if err != nil {
		return nil, err
	}

	req.Close = true

	req.TransferEncoding = []string{"identity"}

	req.Header.Add("Accept", "application/json")
	req.Header.Add("User-Agent", c.UserAgent)

	if options != nil && options.JsonBody != nil {
		req.Header.Set("Content-Type", "application/json")
	}

	if options != nil && options.Headers != nil {
		for key, value := range *options.Headers {
			req.Header.Set(key, value)
		}
	}

	return req, nil
}
Beispiel #4
0
// RequestHeader returns a new set of headers from a request.
func RequestHeader(req *http.Request) *Header {
	return &Header{
		h:       req.Header,
		host:    func() string { return req.Host },
		cl:      func() int64 { return req.ContentLength },
		te:      func() []string { return req.TransferEncoding },
		setHost: func(host string) { req.Host = host },
		setCL:   func(cl int64) { req.ContentLength = cl },
		setTE:   func(te []string) { req.TransferEncoding = te },
	}
}
Beispiel #5
0
// interact queries CouchDB and parses the response.
// method: the name of the HTTP method (POST, PUT, ...)
// url: the URL to interact with
// headers: additional headers to pass to the request
// in: body of the request
// out: a structure to fill in with the returned JSON document
func (p Database) interact(method, u string, headers map[string][]string, in []byte, out interface{}) (int, error) {
	bodyLength := 0
	if in != nil {
		bodyLength = len(in)
		headers["Content-Type"] = []string{"application/json"}
	}
	req := http.Request{
		Method:        method,
		ProtoMajor:    1,
		ProtoMinor:    1,
		Close:         true,
		ContentLength: int64(bodyLength),
		Header:        headers,
	}
	req.TransferEncoding = []string{"chunked"}
	var err error
	req.URL, err = url.Parse(u)
	if err != nil {
		return 0, err
	}
	if in != nil {
		req.Body = ioutil.NopCloser(bytes.NewBuffer(in))
	}
	if req.URL.User != nil {
		if password, ok := req.URL.User.Password(); ok {
			req.SetBasicAuth(req.URL.User.Username(), password)
		}
	}
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", p.Host, p.Port))
	if err != nil {
		return 0, err
	}
	httpConn := httputil.NewClientConn(conn, nil)
	defer httpConn.Close()
	if err := httpConn.Write(&req); err != nil {
		return 0, err
	}
	r, err := httpConn.Read(&req)
	if err != nil && err != httputil.ErrPersistEOF {
		return 0, err
	}
	defer r.Body.Close()
	if r.StatusCode < 200 || r.StatusCode >= 300 {
		b := []byte{}
		r.Body.Read(b)
		return r.StatusCode, fmt.Errorf(r.Status)
	}
	decoder := json.NewDecoder(r.Body)
	if err = decoder.Decode(out); err != nil && err != httputil.ErrPersistEOF {
		return 0, err
	}
	return r.StatusCode, nil
}
Beispiel #6
0
func post(url_ string, body io.ReadCloser, oauthHeaders map[string]string, headers map[string]string) (r *http.Response, err error) {
	var req http.Request
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	req.Header = map[string][]string{
		"Authorization": {"OAuth "},
	}
	req.TransferEncoding = []string{"chunked"}
	if "" != headers["Content-Length"] {
		req.TransferEncoding = []string{""}
		req.ContentLength, err = strconv.ParseInt(headers["Content-Length"], 10, 64)
	}
	req.Body = body

	first := true
	for k, v := range oauthHeaders {
		if first {
			first = false
		} else {
			req.Header["Authorization"][0] += ",\n    "
		}
		req.Header["Authorization"][0] += k + "=\"" + v + "\""
	}

	for k, v := range headers {
		req.Header[k] = []string{v}
	}

	req.URL, err = url.Parse(url_)
	if err != nil {
		return nil, err
	}

	return send(&req)
}
Beispiel #7
0
// NewFastHTTPHandler wraps net/http handler to fasthttp request handler,
// so it can be passed to fasthttp server.
//
// While this function may be used for easy switching from net/http to fasthttp,
// it has the following drawbacks comparing to using manually written fasthttp
// request handler:
//
//     * A lot of useful functionality provided by fasthttp is missing
//       from net/http handler.
//     * net/http -> fasthttp handler conversion has some overhead,
//       so the returned handler will be always slower than manually written
//       fasthttp handler.
//
// So it is advisable using this function only for quick net/http -> fasthttp
// switching. Then manually convert net/http handlers to fasthttp handlers
// according to https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp .
func NewFastHTTPHandler(h http.Handler) fasthttp.RequestHandler {
	return func(ctx *fasthttp.RequestCtx) {
		var r http.Request

		body := ctx.PostBody()
		r.Method = string(ctx.Method())
		r.Proto = "HTTP/1.1"
		r.ProtoMajor = 1
		r.ProtoMinor = 1
		r.RequestURI = string(ctx.RequestURI())
		r.ContentLength = int64(len(body))
		r.Host = string(ctx.Host())
		r.RemoteAddr = ctx.RemoteAddr().String()

		hdr := make(http.Header)
		ctx.Request.Header.VisitAll(func(k, v []byte) {
			sk := string(k)
			sv := string(v)
			switch sk {
			case "Transfer-Encoding":
				r.TransferEncoding = append(r.TransferEncoding, sv)
			default:
				hdr.Set(sk, sv)
			}
		})
		r.Header = hdr
		r.Body = &netHTTPBody{body}
		rURL, err := url.ParseRequestURI(r.RequestURI)
		if err != nil {
			ctx.Logger().Printf("cannot parse requestURI %q: %s", r.RequestURI, err)
			ctx.Error("Internal Server Error", fasthttp.StatusInternalServerError)
			return
		}
		r.URL = rURL

		var w netHTTPResponseWriter
		h.ServeHTTP(&w, &r)

		ctx.SetStatusCode(w.StatusCode())
		for k, vv := range w.Header() {
			for _, v := range vv {
				ctx.Response.Header.Set(k, v)
			}
		}
		ctx.Write(w.body)
	}
}
Beispiel #8
0
// General Request method used by the specialized request methods to create a request
func (c *client) newRequest(method string, id string) (*http.Request, error) {
	request := new(http.Request)
	var err error
	fmt.Println(c)
	request.ProtoMajor = 1
	request.ProtoMinor = 1
	request.TransferEncoding = []string{"chunked"}
	request.Method = method

	// Generate Resource-URI and parse it
	uri := c.resource.String() + id
	fmt.Println(uri)
	if request.URL, err = url.Parse(uri); err != nil {
		return nil, err
	}

	return request, nil
}
// General Request method used by the specialized request methods to create a request
func (client *Client) newRequest(method string, id string) (*http.Request, error) {
	request := new(http.Request)
	var err error

	request.ProtoMajor = 1
	request.ProtoMinor = 1
	request.TransferEncoding = []string{"chunked"}

	request.Method = method

	// Generate Resource-URI and parse it
	targeturl := client.resource.String() + id
	if request.URL, err = url.Parse(targeturl); err != nil {
		return nil, err
	}

	return request, nil
}
Beispiel #10
0
func TestProxyResponse(t *testing.T) {
	var req *http.Request
	var err error

	// Creating a request.
	if req, err = http.NewRequest("GET", "https://www.example.org", nil); err != nil {
		t.Fatal(err)
	}
	req.TransferEncoding = []string{"identity"}

	// Creating a response writer.
	wri := newTestResponseWriter()

	// Executing request.
	proxy.ServeHTTP(wri, req)

	// Verifying response.
	if wri.header.Get("Date") == "" {
		t.Fatal("Expecting a date.")
	}
}
Beispiel #11
0
func (r *Request) StdRequest() *http.Request {
	if r.stdRequest != nil {
		return r.stdRequest
	}
	var req http.Request
	ctx := r.context
	req.Method = r.Method()
	req.Proto = "HTTP/1.1"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.RequestURI = r.URI()
	req.ContentLength = r.Size()
	req.Host = r.Host()
	req.RemoteAddr = r.RemoteAddress()

	hdr := make(http.Header)
	ctx.Request.Header.VisitAll(func(k, v []byte) {
		sk := engine.Bytes2str(k)
		sv := engine.Bytes2str(v)
		switch sk {
		case "Transfer-Encoding":
			req.TransferEncoding = append(req.TransferEncoding, sv)
		default:
			hdr.Set(sk, sv)
		}
	})
	req.Header = hdr
	req.Body = r.Body()
	rURL, err := url.ParseRequestURI(req.RequestURI)
	if err != nil {
		ctx.Logger().Printf("cannot parse requestURI %q: %s", req.RequestURI, err)
		r.response.Error("Internal Server Error")
	}
	req.URL = rURL
	r.stdRequest = &req
	return r.stdRequest
}