// 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) } }
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()) } }
// 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 }
// 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 }
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") } }
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 }
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) }
// 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 }
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 }
// 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) } }
//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) }
// 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 }
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 }
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 }
// 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) }
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} } }
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 }
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 }
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} } }
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) }
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) }
// 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 }, } }
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 }
// 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 }
// 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 }
// 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 }
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) }