Example #1
0
// handle request body
func (conn Conn) handleBody(req *http.Request, body io.Reader) {
	rc, ok := body.(io.ReadCloser)
	if !ok && body != nil {
		rc = ioutil.NopCloser(body)
	}
	req.Body = rc
	switch v := body.(type) {
	case *bytes.Buffer:
		req.ContentLength = int64(v.Len())
	case *bytes.Reader:
		req.ContentLength = int64(v.Len())
	case *strings.Reader:
		req.ContentLength = int64(v.Len())
	case *os.File:
		req.ContentLength = tryGetFileSize(v)
	}
	req.Header.Set(HTTPHeaderContentLength, strconv.FormatInt(req.ContentLength, 10))

	// md5
	if req.Body != nil {
		buf, _ := ioutil.ReadAll(req.Body)
		req.Body = ioutil.NopCloser(bytes.NewReader(buf))
		sum := md5.Sum(buf)
		b64 := base64.StdEncoding.EncodeToString(sum[:])
		req.Header.Set(HTTPHeaderContentMD5, b64)
	}
}
Example #2
0
func inferContentLength(req *http.Request, body io.ReadSeeker) {
	if body == nil {
		return
	}
	switch v := body.(type) {
	case *bytes.Reader:
		req.ContentLength = int64(v.Len())
	case *strings.Reader:
		req.ContentLength = int64(v.Len())
	}
}
Example #3
0
// Returns a map of all of the oauth_* (including signature) parameters for the
// given request, and the signature base string used to generate the signature.
func (s *HmacSha1Signer) GetOAuthParams(request *http.Request, clientConfig *ClientConfig, userConfig *UserConfig, nonce string, timestamp string) (map[string]string, string) {
	oauthParams := map[string]string{
		"oauth_consumer_key":     clientConfig.ConsumerKey,
		"oauth_nonce":            nonce,
		"oauth_signature_method": "HMAC-SHA1",
		"oauth_timestamp":        timestamp,
		"oauth_version":          "1.0",
	}
	tokenKey, tokenSecret := userConfig.GetToken()
	if tokenKey != "" {
		oauthParams["oauth_token"] = tokenKey
	}
	signingParams := map[string]string{}
	for key, value := range oauthParams {
		signingParams[key] = value
	}
	for key, value := range request.URL.Query() {
		//TODO: Support multiple parameters with the same name.
		signingParams[key] = value[0]
	}
	if request.Body != nil && request.Header.Get("Content-Type") == "application/x-www-form-urlencoded" {
		request.ParseForm()
		for key, value := range request.Form {
			//TODO: Support multiple parameters with the same name.
			signingParams[key] = value[0]
		}
		// Calling ParseForm clears out the reader.  It may be
		// necessary to do this in a less destructive way, but for
		// right now, this code reinitializes the body of the request.
		var body io.Reader = strings.NewReader(request.Form.Encode())
		rc, ok := body.(io.ReadCloser)
		if !ok && body != nil {
			rc = ioutil.NopCloser(body)
		}
		request.Body = rc
		if body != nil {
			switch v := body.(type) {
			case *strings.Reader:
				request.ContentLength = int64(v.Len())
			case *bytes.Buffer:
				request.ContentLength = int64(v.Len())
			}
		}
	}
	signingUrl := fmt.Sprintf("%v://%v%v", request.URL.Scheme, request.URL.Host, request.URL.Path)
	signatureParts := []string{
		request.Method,
		url.QueryEscape(signingUrl),
		s.encodeParameters(signingParams)}
	signatureBase := strings.Join(signatureParts, "&")
	oauthParams["oauth_signature"] = s.GetSignature(clientConfig.ConsumerSecret, tokenSecret, signatureBase)
	return oauthParams, signatureBase
}
Example #4
0
File: request.go Project: kr/spdy
// ReadRequest reads an HTTP request. The header is taken from h,
// which must include the SPDY-specific fields starting with ':'.
// If r is not nil, the body will be read from r. If t is not nil,
// the trailer will be taken from t after the body is finished.
func ReadRequest(h, t http.Header, r io.Reader) (*http.Request, error) {
	req := new(http.Request)
	req.Header = make(http.Header)
	copyHeader(req.Header, h)
	path := h.Get(":path")
	if path == "" {
		return nil, errors.New("missing path")
	}
	if path[0] != '/' {
		return nil, errors.New("invalid path: " + path)
	}
	req.URL = &url.URL{
		Scheme: h.Get(":scheme"),
		Path:   path,
		Host:   h.Get(":host"),
	}
	req.Close = true
	req.Method = h.Get(":method")
	req.Host = h.Get(":host")
	req.Proto = h.Get(":version")
	var ok bool
	if req.ProtoMajor, req.ProtoMinor, ok = http.ParseHTTPVersion(req.Proto); !ok {
		return nil, errors.New("bad http version: " + req.Proto)
	}
	req.Header.Del("Host")

	cl := strings.TrimSpace(req.Header.Get("Content-Length"))
	if cl != "" {
		n, err := parseContentLength(cl)
		if err != nil {
			return nil, err
		}
		req.ContentLength = n
	} else {
		// Assume GET request has no body by default.
		if req.Method != "GET" {
			req.ContentLength = -1
		}
		req.Header.Del("Content-Length")
	}

	// TODO(kr): content length / limit reader?
	if r == nil {
		r = eofReader
	}
	if t != nil {
		req.Body = &body{r: r, hdr: req, trailer: t}
	} else {
		req.Body = &body{r: r}
	}
	return req, nil
}
Example #5
0
func main() {
	if 3 <= len(os.Args) && len(os.Args) <= 5 {
		method := os.Args[1]
		ackordurl, _ := url.Parse(os.Args[2])

		request := new(http.Request)

		if len(os.Args) == 3 && method == "GET" {
		} else if len(os.Args) == 3 && method == "DELETE" {
		} else if len(os.Args) == 4 && method == "PUT" {
			request.Header = make(http.Header)
			request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
			myBody := bytes.NewBufferString(fmt.Sprintf("value=%s", os.Args[3]))
			request.Body = ioutil.NopCloser(myBody)
			request.ContentLength = int64(myBody.Len())
		} else if len(os.Args) == 5 && method == "POST" {
			request.Header = make(http.Header)
			request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
			myBody := bytes.NewBufferString(fmt.Sprintf("key=%s&value=%s", os.Args[3], os.Args[4]))
			request.Body = ioutil.NopCloser(myBody)
			request.ContentLength = int64(myBody.Len())
		} else {
			fmt.Println("wrong method")
			return
		}

		client := new(http.Client)
		request.Method = method
		request.URL = ackordurl

		bb, _ := httputil.DumpRequest(request, true)
		fmt.Println("Request: " + string(bb[:]))

		response, err := client.Do(request)
		if err != nil {
			fmt.Println(err.Error())
			return
		}

		rb, _ := httputil.DumpResponse(response, true)
		fmt.Println("Response body: " + string(rb[:]))

	} else {
		fmt.Println("rester POST http://localhost:12080/storage/ MyText \"Some text here.\"")
		fmt.Println("rester GET http://localhost:12080/storage/MyText")
		fmt.Println("rester PUT http://localhost:12080/storage/MyText \"Some other text.\"")
		fmt.Println("rester DELETE http://localhost:12080/storage/MyText")
	}
}
Example #6
0
func DoPost(m map[string]string) (success bool, response string) {
	if AppKey == "" || AppSecret == "" {
		return false, "AppKey or AppSecret is requierd!"
	}

	body, size := getRequestBody(m)
	client := &http.Client{}
	var req *http.Request
	var err error
	if !UseHTTP {
		req, err = http.NewRequest("POST", URL_HTTPS, body)
	} else {
		req, err = http.NewRequest("POST", URL_HTTP, body)
	}
	if err != nil {
		return false, err.Error()
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.ContentLength = size

	resp, err := client.Do(req)
	if err != nil {
		response = err.Error()
		return
	}
	defer resp.Body.Close()

	data, _ := ioutil.ReadAll(resp.Body)
	response = string(data)
	if strings.Contains(response, "success") {
		return true, response
	}
	return false, response
}
Example #7
0
func (c *Client) sent(method string, u *url.URL, bodyType string, body io.Reader, bodyLength int) (resp *http.Response, err error) {
	var req *http.Request

	upperMethod := strings.ToUpper(method)
	switch upperMethod {
	case "GET":
		fallthrough
	case "POST":
		fallthrough
	case "PATCH":
		fallthrough
	case "PUT":
		fallthrough
	case "DELETE":
		req, err = http.NewRequest(upperMethod, u.String(), body)
		req.Header.Set("Content-Type", bodyType)
		if bodyLength > 0 {
			req.ContentLength = int64(bodyLength)
		}
		if err != nil {
			return
		}
	default:
		err = errors.New("unsupport method: " + method)
		return
	}

	return c.do(req)
}
Example #8
0
File: parse.go Project: stoyan/rell
// Do performs a Parse API call. This method modifies the request and adds the
// Authentication headers. The body is JSON encoded and for responses in the
// 2xx or 3xx range the response will be JSON decoded into result, for others
// an error of type Error will be returned.
func (c *Client) Do(req *http.Request, body, result interface{}) (*http.Response, error) {
	// we need to buffer as Parse requires a Content-Length
	if body != nil {
		bd, err := json.Marshal(body)
		if err != nil {
			return nil, err
		}
		if req.Header == nil {
			req.Header = make(http.Header)
		}
		req.Header.Set("Content-Type", "application/json")
		req.Body = ioutil.NopCloser(bytes.NewReader(bd))
		req.ContentLength = int64(len(bd))
	}

	res, err := c.RoundTrip(req)
	if err != nil {
		return res, err
	}
	defer res.Body.Close()

	if result != nil {
		if err := json.NewDecoder(res.Body).Decode(result); err != nil {
			return res, err
		}
	}
	return res, nil
}
Example #9
0
func (e Post) Target(r *http.Request) {
	r.Body = ioutil.NopCloser(bytes.NewBuffer(e.Body))
	r.ContentLength = int64(len(e.Body))
	r.Header.Set("Content-Type", e.ContentType)
	r.Method = "POST"
	r.URL = e.URL
}
Example #10
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) {
			hdr.Set(string(k), string(v))
		})
		r.Header = hdr
		r.Body = &netHTTPBody{body}

		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)
	}
}
Example #11
0
//CallAPI sends an HTTP request using "method" to "url".
//For uploading / sending file, caller needs to set the "content".  Otherwise,
//set it to zero length []byte. If Header fields need to be set, then set it in
// "h".  "h" needs to be even numbered, i.e. pairs of field name and the field
//content.
//
//fileContent, err := ioutil.ReadFile("fileName.ext");
//
//resp, err := CallAPI("PUT", "http://domain/hello/", &fileContent,
//"Name", "world")
//
//is similar to: curl -X PUT -H "Name: world" -T fileName.ext
//http://domain/hello/
func CallAPI(method, url string, content *[]byte, h ...string) (*http.Response, error) {
	if len(h)%2 == 1 { //odd #
		return nil, errors.New("syntax err: # header != # of values")
	}
	//I think the above err check is unnecessary and wastes cpu cycle, since
	//len(h) is not determined at run time. If the coder puts in odd # of args,
	//the integration testing should catch it.
	//But hey, things happen, so I decided to add it anyway, although you can
	//comment it out, if you are confident in your test suites.
	var req *http.Request
	var err error
	req, err = http.NewRequest(method, url, nil)
	if err != nil {
		return nil, err
	}
	for i := 0; i < len(h)-1; i = i + 2 {
		req.Header.Set(h[i], h[i+1])
	}
	req.ContentLength = int64(len(*content))
	if req.ContentLength > 0 {
		req.Body = readCloser{bytes.NewReader(*content)}
		//req.Body = *(new(io.ReadCloser)) //these 3 lines do not work but I am
		//req.Body.Read(content)           //keeping them here in case I wonder why
		//req.Body.Close()                 //I did not implement it this way :)
	}
	return (new(http.Client)).Do(req)
}
Example #12
0
// putCAS is used to do a PUT with optional CAS
func (c *Client) putCAS(key string, value []byte, flags, index uint64, cas bool) (bool, error) {
	url := c.pathURL(key)
	query := url.Query()
	if cas {
		query.Set("cas", strconv.FormatUint(index, 10))
	}
	query.Set("flags", strconv.FormatUint(flags, 10))
	url.RawQuery = query.Encode()
	req := http.Request{
		Method: "PUT",
		URL:    url,
		Body:   ioutil.NopCloser(bytes.NewReader(value)),
	}
	req.ContentLength = int64(len(value))
	resp, err := c.config.HTTPClient.Do(&req)
	if err != nil {
		return false, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return false, fmt.Errorf("unexpected response code: %d", resp.StatusCode)
	}
	var buf bytes.Buffer
	if _, err := io.Copy(&buf, resp.Body); err != nil {
		return false, fmt.Errorf("failed to read response: %v", err)
	}
	res := strings.Contains(string(buf.Bytes()), "true")
	return res, nil
}
Example #13
0
func (s *svc) handleFinderRequest(w http.ResponseWriter, r *http.Request) error {
	log := keys.MustGetLog(r)

	/*
	   Many webservers will not cooperate well with Finder PUT requests,
	   because it uses 'Chunked' transfer encoding for the request body.
	   The symptom of this problem is that Finder sends files to the
	   server, but they arrive as 0-length files in PHP.
	   If we don't do anything, the user might think they are uploading
	   files successfully, but they end up empty on the server. Instead,
	   we throw back an error if we detect this.
	   The reason Finder uses Chunked, is because it thinks the files
	   might change as it's being uploaded, and therefore the
	   Content-Length can vary.
	   Instead it sends the X-Expected-Entity-Length header with the size
	   of the file at the very start of the request. If this header is set,
	   but we don't get a request body we will fail the request to
	   protect the end-user.
	*/
	log.Warnf("intercepting Finder problem (Content-Length:%s X-Expected-Entity-Length:%s)", r.Header.Get("Content-Length"), r.Header.Get("X-Expected-Entity-Length"))

	// The best mitigation to this problem is to tell users to not use crappy Finder.
	// Another possible mitigation is to change the use the value of X-Expected-Entity-Length header in the Content-Length header.
	expected := r.Header.Get("X-Expected-Entity-Length")
	expectedInt, err := strconv.ParseInt(expected, 10, 64)
	if err != nil {
		log.WithError(err).Error("X-Expected-Entity-Length is not a number")
		w.WriteHeader(http.StatusBadRequest)
		return err
	}
	r.ContentLength = expectedInt
	return nil
}
Example #14
0
func (h *ProxyHandler) PreRequestEncryptionHook(r *http.Request, innerRequest *http.Request, info *BucketInfo) (*CountingHash, error) {
	if info == nil || info.Config == nil || info.Config.EncryptionKey == "" || r.Method != "PUT" {
		return nil, nil
	}

	// If this is a "copy" PUT, we should send no body at all
	for k, _ := range r.Header {
		if strings.HasPrefix(strings.ToLower(k), "x-amz-copy-source") {
			return nil, nil
		}
	}

	encryptedInput, extralen, err := SetupWriteEncryption(r.Body, info)

	if err != nil {
		return nil, err
	}

	// Since encryption transforms the data, after the inner request succeeds,
	// we'll match the MD5s of the transformed data, and mangle the etag in the
	// response we send to the client with the MD5 of the untransformed data if
	// they match.
	innerBodyHash := NewCountingHash(md5.New())
	teereader := io.TeeReader(encryptedInput, innerBodyHash)
	innerRequest.Body = ioutil.NopCloser(teereader)

	if length := innerRequest.ContentLength; length != -1 {
		innerRequest.ContentLength += extralen
		innerRequest.Header.Set("Content-Length", strconv.FormatInt(innerRequest.ContentLength, 10))
	}

	InfoLogger.Print("Encrypting the request")

	return innerBodyHash, nil
}
Example #15
0
// ApplyTo sets the requests Method to PUT, URL and Body
func (p Put) ApplyTo(req *http.Request) {
	req.Method = "PUT"
	req.URL = p.URL
	req.Body = ioutil.NopCloser(bytes.NewBuffer(p.Body))
	req.ContentLength = int64(len(p.Body))
	req.Header.Set("Content-Type", p.ContentType)
}
Example #16
0
func (this *KeepClient) uploadToKeepServer(host string, hash string, body io.ReadCloser,
	upload_status chan<- uploadStatus, expectedLength int64, requestID int32) {

	var req *http.Request
	var err error
	var url = fmt.Sprintf("%s/%s", host, hash)
	if req, err = http.NewRequest("PUT", url, nil); err != nil {
		log.Printf("[%08x] Error creating request PUT %v error: %v", requestID, url, err.Error())
		upload_status <- uploadStatus{err, url, 0, 0, ""}
		body.Close()
		return
	}

	req.ContentLength = expectedLength
	if expectedLength > 0 {
		// http.Client.Do will close the body ReadCloser when it is
		// done with it.
		req.Body = body
	} else {
		// "For client requests, a value of 0 means unknown if Body is
		// not nil."  In this case we do want the body to be empty, so
		// don't set req.Body.  However, we still need to close the
		// body ReadCloser.
		body.Close()
	}

	req.Header.Add("Authorization", fmt.Sprintf("OAuth2 %s", this.Arvados.ApiToken))
	req.Header.Add("Content-Type", "application/octet-stream")
	req.Header.Add(X_Keep_Desired_Replicas, fmt.Sprint(this.Want_replicas))

	var resp *http.Response
	if resp, err = this.Client.Do(req); err != nil {
		log.Printf("[%08x] Upload failed %v error: %v", requestID, url, err.Error())
		upload_status <- uploadStatus{err, url, 0, 0, ""}
		return
	}

	rep := 1
	if xr := resp.Header.Get(X_Keep_Replicas_Stored); xr != "" {
		fmt.Sscanf(xr, "%d", &rep)
	}

	defer resp.Body.Close()
	defer io.Copy(ioutil.Discard, resp.Body)

	respbody, err2 := ioutil.ReadAll(&io.LimitedReader{R: resp.Body, N: 4096})
	response := strings.TrimSpace(string(respbody))
	if err2 != nil && err2 != io.EOF {
		log.Printf("[%08x] Upload %v error: %v response: %v", requestID, url, err2.Error(), response)
		upload_status <- uploadStatus{err2, url, resp.StatusCode, rep, response}
	} else if resp.StatusCode == http.StatusOK {
		log.Printf("[%08x] Upload %v success", requestID, url)
		upload_status <- uploadStatus{nil, url, resp.StatusCode, rep, response}
	} else {
		log.Printf("[%08x] Upload %v error: %v response: %v", requestID, url, resp.StatusCode, response)
		upload_status <- uploadStatus{errors.New(resp.Status), url, resp.StatusCode, rep, response}
	}
}
Example #17
0
func makeRequest(params map[string]string) (*http.Request, error) {
	r := new(http.Request)
	r.Method = params["METHOD"]
	if r.Method == "" {
		return nil, errors.New("mongrel2: no METHOD")
	}

	r.Proto = params["VERSION"]
	var ok bool
	r.ProtoMajor, r.ProtoMinor, ok = http.ParseHTTPVersion(r.Proto)
	if !ok {
		return nil, errors.New("mongrel2: invalid protocol version")
	}

	r.Trailer = http.Header{}
	r.Header = http.Header{}

	r.Host = params["Host"]
	r.Header.Set("Referer", params["Referer"])
	r.Header.Set("User-Agent", params["User-Agent"])

	if lenstr := params["Content-Length"]; lenstr != "" {
		clen, err := strconv.ParseInt(lenstr, 10, 64)
		if err != nil {
			return nil, errors.New("mongrel2: bad Content-Length")
		}
		r.ContentLength = clen
	}

	for k, v := range params {
		if !skipHeader[k] {
			r.Header.Add(k, v)
		}
	}

	// TODO: cookies

	if r.Host != "" {
		url_, err := url.Parse("http://" + r.Host + params["URI"])
		if err != nil {
			return nil, errors.New("mongrel2: failed to parse host and URI into a URL")
		}
		r.URL = url_
	}
	if r.URL == nil {
		url_, err := url.Parse(params["URI"])
		if err != nil {
			return nil, errors.New("mongrel2: failed to parse URI into a URL")
		}
		r.URL = url_
	}

	// TODO: how do we know if we're using HTTPS?
	// TODO: fill in r.RemoteAddr

	return r, nil
}
Example #18
0
func marshalRequestBody(r *http.Request, body interface{}) error {
	newBody, err := json.Marshal(body)
	if err != nil {
		return err
	}
	r.Body = ioutil.NopCloser(bytes.NewReader(newBody))
	r.ContentLength = int64(len(newBody))
	return nil
}
Example #19
0
func (this KeepClient) uploadToKeepServer(host string, hash string, body io.ReadCloser,
	upload_status chan<- uploadStatus, expectedLength int64) {

	log.Printf("Uploading %s to %s", hash, host)

	var req *http.Request
	var err error
	var url = fmt.Sprintf("%s/%s", host, hash)
	if req, err = http.NewRequest("PUT", url, nil); err != nil {
		upload_status <- uploadStatus{err, url, 0, 0, ""}
		body.Close()
		return
	}

	if expectedLength > 0 {
		req.ContentLength = expectedLength
	}

	req.Header.Add("Authorization", fmt.Sprintf("OAuth2 %s", this.Arvados.ApiToken))
	req.Header.Add("Content-Type", "application/octet-stream")

	if this.Using_proxy {
		req.Header.Add(X_Keep_Desired_Replicas, fmt.Sprint(this.Want_replicas))
	}

	req.Body = body

	var resp *http.Response
	if resp, err = this.Client.Do(req); err != nil {
		upload_status <- uploadStatus{err, url, 0, 0, ""}
		body.Close()
		return
	}

	rep := 1
	if xr := resp.Header.Get(X_Keep_Replicas_Stored); xr != "" {
		fmt.Sscanf(xr, "%d", &rep)
	}

	defer resp.Body.Close()
	defer io.Copy(ioutil.Discard, resp.Body)

	respbody, err2 := ioutil.ReadAll(&io.LimitedReader{resp.Body, 4096})
	if err2 != nil && err2 != io.EOF {
		upload_status <- uploadStatus{err2, url, resp.StatusCode, rep, string(respbody)}
		return
	}

	locator := strings.TrimSpace(string(respbody))

	if resp.StatusCode == http.StatusOK {
		upload_status <- uploadStatus{nil, url, resp.StatusCode, rep, locator}
	} else {
		upload_status <- uploadStatus{errors.New(resp.Status), url, resp.StatusCode, rep, locator}
	}
}
Example #20
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
}
func Test_unmarshallOrder_should_unmarshal_with_error(t *testing.T) {
	// given
	order := new(commons.Order)
	var req http.Request
	req.Body = nopCloser{bytes.NewBuffer(make([]byte, 0))}
	req.ContentLength = int64(0)
	// when
	err := commons.UnmarshalOrderFromHttp(&req, order)
	assert.NotNil(t, err)
}
Example #22
0
func reverseProxy(w http.ResponseWriter, req *http.Request) {
	logRequest(req)

	if rSensitivePath.MatchString(req.URL.Path) {
		w.WriteHeader(http.StatusForbidden)
		return
	}

	outReq := new(http.Request)
	outReq.Method = req.Method
	outReq.URL = &url.URL{
		Scheme:   "http",
		Host:     host,
		Path:     req.URL.Path,
		RawQuery: req.URL.RawQuery,
	}
	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1
	outReq.Header = make(http.Header)
	outReq.Body = req.Body
	outReq.ContentLength = req.ContentLength
	outReq.Host = host

	for _, h := range removeHeaders {
		req.Header.Del(h)
	}
	copyHeader(outReq.Header, req.Header)
	outReq.Header.Set("Host", host)
	outReq.Header.Set("Referer", baseURL)
	outReq.Header.Set("Origin", baseURL)

	resp, err := send(outReq)
	if err != nil {
		log.Printf("proxy error: %v", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	defer resp.Body.Close()

	for _, h := range removeHeaders {
		resp.Header.Del(h)
	}
	if loc := resp.Header.Get("Location"); loc != "" {
		if u, err := url.Parse(loc); err == nil && u.Host == host {
			u.Scheme = "http"
			u.Host = req.Host
			resp.Header.Set("Location", u.String())
		}
	}
	copyHeader(w.Header(), resp.Header)
	w.WriteHeader(resp.StatusCode)

	io.Copy(w, resp.Body)
}
Example #23
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 },
	}
}
Example #24
0
func (client *RPCClient) RPCCall(methodName string,
	args ...interface{}) (interface{}, *rpc.Fault, *rpc.Error) {
	buf := bytes.NewBufferString("")
	berr := Marshal(buf, methodName, args)
	if berr != nil {
		return nil, nil, berr
	}

	var req http.Request
	req.URL = client.url
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = false
	req.Body = nopCloser{buf}
	req.Header = map[string][]string{
		"Content-Type": {"text/xml"},
	}
	req.RawURL = "/RPC"
	req.ContentLength = int64(buf.Len())

	if client.conn == nil {
		var cerr *rpc.Error
		if client.conn, cerr = rpc.Open(client.url); cerr != nil {
			return nil, nil, cerr
		}
	}

	if werr := req.Write(client.conn); werr != nil {
		client.conn.Close()
		return nil, nil, &rpc.Error{Msg: werr.String()}
	}

	reader := bufio.NewReader(client.conn)
	resp, rerr := http.ReadResponse(reader, &req)
	if rerr != nil {
		client.conn.Close()
		return nil, nil, &rpc.Error{Msg: rerr.String()}
	} else if resp == nil {
		rrerr := fmt.Sprintf("ReadResponse for %s returned nil response\n",
			methodName)
		return nil, nil, &rpc.Error{Msg: rrerr}
	}

	_, pval, perr, pfault := Unmarshal(resp.Body)

	if resp.Close {
		resp.Body.Close()
		client.conn = nil
	}

	return pval, pfault, perr
}
Example #25
0
// ServeHTTP routes a graphite render query to a backend
// graphite server based on its content. If the query contains
// metrics that map one (and only one) of the prefixes in
// a configuration, ServeHTTP will strip the prefix and proxy
// the request to the appropriate backend server.
func (c *Config) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/render" {
		notfound(w)
		return
	}

	if err := r.ParseForm(); err != nil {
		log.Println(err)
		badrequest(w)
		return
	}

	targets := r.Form["target"]
	queries := make([]*query.Query, 0, len(targets))
	for _, target := range targets {
		if q, err := query.Parse(target); err != nil {
			w.WriteHeader(400)
			fmt.Fprintf(w, "Invalid query %q: %v", target, err)
			return
		} else {
			queries = append(queries, q)
		}
	}
	form, server := c.proxyTargets(queries)
	for k, v := range r.Form {
		if k != "target" {
			form[k] = v
		}
	}

	if server.ReverseProxy == nil {
		log.Printf("no backend for %q", queries)
		badrequest(w)
		return
	}

	switch r.Method {
	case "GET":
		r.URL.RawQuery = form.Encode()
		r.Host = server.url.Host
		if c.Debug {
			if dmp, err := httputil.DumpRequest(r, false); err == nil {
				log.Printf("%s", dmp)
			}
		}
	case "POST":
		s := form.Encode()
		r.ContentLength = int64(len(s))
		r.Body = ioutil.NopCloser(
			strings.NewReader(s))
	}
	server.ServeHTTP(w, r)
}
func createTestPOSTRequest(reqUrl string, content string, contentType string) *http.Request {
	request := new(http.Request)
	request.Method = "POST"
	request.URL, _ = url.Parse(reqUrl)
	request.Body = ioutil.NopCloser(strings.NewReader(content))
	request.ContentLength = int64(len(content))
	request.Header = make(http.Header)
	request.Header.Add("Content-Type", contentType)
	request.Header.Add("User-Agent", "Unit-Test")
	request.Header.Add("Accept", "application/json")

	return request
}
Example #27
0
File: boomer.go Project: bachp/boom
// cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map.
func cloneRequest(r *http.Request, body string) *http.Request {
	// shallow copy of the struct
	r2 := new(http.Request)
	*r2 = *r
	// deep copy of the Header
	r2.Header = make(http.Header, len(r.Header))
	for k, s := range r.Header {
		r2.Header[k] = append([]string(nil), s...)
	}
	r2.Body = ioutil.NopCloser(strings.NewReader(body))
	r2.ContentLength = int64(len(body))
	return r2
}
Example #28
0
// Ensure that the supplied request has a correct ContentLength field set.
func fillInContentLength(req *http.Request) (err error) {
	body := req.Body
	if body == nil {
		req.ContentLength = 0
		return
	}

	// Make a copy.
	contents, err := ioutil.ReadAll(req.Body)
	if err != nil {
		err = fmt.Errorf("ReadAll: %v", err)
		return
	}

	req.Body.Close()

	// Fill in the content length and restore the body.
	req.ContentLength = int64(len(contents))
	req.Body = ioutil.NopCloser(bytes.NewReader(contents))

	return
}
Example #29
0
func (h *HTTPSender) buildBaseRequest(contextPath string, method string, headers map[string][]string, bodyReader *bytes.Reader) *http.Request {
	var req http.Request
	req.Method = h.method
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = false
	req.Header = h.headers
	req.URL = h.parsedContextPath
	req.URL.Host = h.hosts[h.currentHost]
	req.Body = ioutil.NopCloser(bodyReader)
	req.ContentLength = int64(bodyReader.Len())
	return &req
}
func Test_unmarshallOrder_should_unmarshal_without_error(t *testing.T) {
	// given
	expectedOrder := commons.Order{Id: 1, Quantity: 5, Type: commons.Beer, CallBackUrl: "http://callback.com/money"}
	order := new(commons.Order)
	body, _ := json.Marshal(expectedOrder)
	var req http.Request
	req.Body = nopCloser{bytes.NewBuffer(body)}
	req.ContentLength = int64(len(body))
	// when
	err := commons.UnmarshalOrderFromHttp(&req, order)
	assert.Nil(t, err)
	assert.Equal(t, expectedOrder, *order)
}