Пример #1
0
func (client ApiClient) do(req *http.Request, body interface{}, responseBody interface{}) error {
	var buf *bytes.Buffer
	if body != nil {
		switch body.(type) {
		case io.Reader:
			req.Body = ioutil.NopCloser(body.(io.Reader))
		default:
			buf = new(bytes.Buffer)
			encoder := client.encoder(buf)
			if err := encoder.Encode(body); err != nil {
				return err
			}
			req.Body = ioutil.NopCloser(buf)
		}
	}

	if resp, err := http.DefaultClient.Do(req); err != nil {
		return err
	} else if err = client.errorFromResponse(resp); err != nil {
		return err
	} else {
		if responseBody != nil {
			defer resp.Body.Close()
			decoder := client.decoder(resp.Body)
			return decoder.Decode(responseBody)
		}
		return nil
	}
}
Пример #2
0
func CopyHttpRequest(r *http.Request) *http.Request {
	reqCopy := new(http.Request)

	if r == nil {
		return reqCopy
	}

	*reqCopy = *r

	if r.Body != nil {
		defer r.Body.Close()

		// Buffer body data
		var bodyBuffer bytes.Buffer
		bodyBuffer2 := new(bytes.Buffer)

		io.Copy(&bodyBuffer, r.Body)
		*bodyBuffer2 = bodyBuffer

		// Create new ReadClosers so we can split output
		r.Body = ioutil.NopCloser(&bodyBuffer)
		reqCopy.Body = ioutil.NopCloser(bodyBuffer2)
	}

	return reqCopy
}
Пример #3
0
// dispatchRequest sends a request to the server, and interprets the response.
// Client-side errors will return an empty response and a non-nil error.  For
// server-side errors however (i.e. responses with a non 2XX status code), the
// returned error will be ServerError and the returned body will reflect the
// server's response.  If the server returns a 503 response with a 'Retry-after'
// header, the request will be transparenty retried.
func (client Client) dispatchRequest(request *http.Request) ([]byte, error) {
	// First, store the request's body into a byte[] to be able to restore it
	// after each request.
	bodyContent, err := readAndClose(request.Body)
	if err != nil {
		return nil, err
	}
	for retry := 0; retry < NumberOfRetries; retry++ {
		// Restore body before issuing request.
		newBody := ioutil.NopCloser(bytes.NewReader(bodyContent))
		request.Body = newBody
		body, err := client.dispatchSingleRequest(request)
		// If this is a 503 response with a non-void "Retry-After" header: wait
		// as instructed and retry the request.
		if err != nil {
			serverError, ok := err.(ServerError)
			if ok && serverError.StatusCode == http.StatusServiceUnavailable {
				retry_time_int, errConv := strconv.Atoi(serverError.Header.Get(RetryAfterHeaderName))
				if errConv == nil {
					select {
					case <-time.After(time.Duration(retry_time_int) * time.Second):
					}
					continue
				}
			}
		}
		return body, err
	}
	// Restore body before issuing request.
	newBody := ioutil.NopCloser(bytes.NewReader(bodyContent))
	request.Body = newBody
	return client.dispatchSingleRequest(request)
}
Пример #4
0
func (t *logTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	var buf bytes.Buffer

	os.Stdout.Write([]byte("\n[request]\n"))
	if req.Body != nil {
		req.Body = ioutil.NopCloser(&readButCopy{req.Body, &buf})
	}
	req.Write(os.Stdout)
	if req.Body != nil {
		req.Body = ioutil.NopCloser(&buf)
	}
	os.Stdout.Write([]byte("\n[/request]\n"))

	res, err := t.rt.RoundTrip(req)

	fmt.Printf("[response]\n")
	if err != nil {
		fmt.Printf("ERROR: %v", err)
	} else {
		body := res.Body
		res.Body = nil
		res.Write(os.Stdout)
		if body != nil {
			res.Body = ioutil.NopCloser(&echoAsRead{body})
		}
	}

	return res, err
}
Пример #5
0
func ReadBody(req *http.Request) *string {
	save := req.Body
	var err error
	if req.Body == nil {
		req.Body = nil
	} else {
		save, req.Body, err = drainBody(req.Body)
		if err != nil {
			return nil
		}
	}
	b := bytes.NewBuffer([]byte(""))
	chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked"
	if req.Body == nil {
		return nil
	}
	var dest io.Writer = b
	if chunked {
		dest = httputil.NewChunkedWriter(dest)
	}
	_, err = io.Copy(dest, req.Body)
	if chunked {
		dest.(io.Closer).Close()
	}
	req.Body = save
	body := b.String()
	return &body
}
Пример #6
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)
	}
}
func (k *AuthKey) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
	thisConfig := k.TykMiddleware.Spec.APIDefinition.Auth

	authHeaderValue := r.Header.Get(thisConfig.AuthHeaderName)
	if thisConfig.UseParam {
		tempRes := new(http.Request)
		*tempRes = *r

		defer r.Body.Close()

		// Buffer body data - don't like thi but we would otherwise drain the request body
		var bodyBuffer bytes.Buffer
		bodyBuffer2 := new(bytes.Buffer)

		k.copyResponse(&bodyBuffer, r.Body)
		*bodyBuffer2 = bodyBuffer

		// Create new ReadClosers so we can split output
		r.Body = ioutil.NopCloser(&bodyBuffer)
		tempRes.Body = ioutil.NopCloser(bodyBuffer2)

		// Set hte header name
		authHeaderValue = tempRes.FormValue(thisConfig.AuthHeaderName)
	}

	if authHeaderValue == "" {
		// No header value, fail
		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": r.RemoteAddr,
		}).Info("Attempted access with malformed header, no auth header found.")

		return errors.New("Authorization field missing"), 400
	}

	// Check if API key valid
	thisSessionState, keyExists := k.TykMiddleware.CheckSessionAndIdentityForValidKey(authHeaderValue)
	if !keyExists {
		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": r.RemoteAddr,
			"key":    authHeaderValue,
		}).Info("Attempted access with non-existent key.")

		// Fire Authfailed Event
		AuthFailed(k.TykMiddleware, r, authHeaderValue)

		// Report in health check
		ReportHealthCheckValue(k.Spec.Health, KeyFailure, "1")

		return errors.New("Key not authorised"), 403
	}

	// Set session state on context, we will need it later
	context.Set(r, SessionData, thisSessionState)
	context.Set(r, AuthHeaderValue, authHeaderValue)

	return nil, 200
}
Пример #8
0
// DumpRequest returns the as-received wire representation of req,
// optionally including the request body, for debugging.
// DumpRequest is semantically a no-op, but in order to
// dump the body, it reads the body data into memory and
// changes req.Body to refer to the in-memory copy.
// The documentation for http.Request.Write details which fields
// of req are used.
func DumpRequest(req *http.Request, body bool) (dump []byte, err error) {
	save := req.Body
	if !body || req.Body == nil {
		req.Body = nil
	} else {
		save, req.Body, err = drainBody(req.Body)
		if err != nil {
			return
		}
	}

	var b bytes.Buffer

	fmt.Fprintf(&b, "%s %s HTTP/%d.%d\r\n", valueOrDefault(req.Method, "GET"),
		req.URL.RequestURI(), req.ProtoMajor, req.ProtoMinor)

	host := req.Host
	if host == "" && req.URL != nil {
		host = req.URL.Host
	}
	if host != "" {
		fmt.Fprintf(&b, "Host: %s\r\n", host)
	}

	chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked"
	if len(req.TransferEncoding) > 0 {
		fmt.Fprintf(&b, "Transfer-Encoding: %s\r\n", strings.Join(req.TransferEncoding, ","))
	}
	if req.Close {
		fmt.Fprintf(&b, "Connection: close\r\n")
	}

	err = req.Header.WriteSubset(&b, reqWriteExcludeHeaderDump)
	if err != nil {
		return
	}

	io.WriteString(&b, "\r\n")

	if req.Body != nil {
		var dest io.Writer = &b
		if chunked {
			dest = NewChunkedWriter(dest)
		}
		_, err = io.Copy(dest, req.Body)
		if chunked {
			dest.(io.Closer).Close()
			io.WriteString(&b, "\r\n")
		}
	}

	req.Body = save
	if err != nil {
		return
	}
	dump = b.Bytes()
	return
}
Пример #9
0
// captureRequest saves request for later playback
func (hf *Hoverfly) captureRequest(req *http.Request) (*http.Response, error) {

	// this is mainly for testing, since when you create
	if req.Body == nil {
		req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte("")))
	}

	reqBody, err := ioutil.ReadAll(req.Body)

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"mode":  "capture",
		}).Error("Got error when reading request body")
	}

	// outputting request body if verbose logging is set
	log.WithFields(log.Fields{
		"body": string(reqBody),
		"mode": "capture",
	}).Debug("got request body")

	// forwarding request
	req.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))

	req, resp, err := hf.doRequest(req)

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"mode":  "capture",
		}).Error("Got error when reading body after being modified by middleware")
	}

	reqBody, err = ioutil.ReadAll(req.Body)
	req.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))

	if err == nil {
		respBody, err := extractBody(resp)

		if err != nil {

			log.WithFields(log.Fields{
				"error": err.Error(),
				"mode":  "capture",
			}).Error("Failed to copy response body.")

			return resp, err
		}

		// saving response body with request/response meta to cache
		hf.save(req, reqBody, resp, respBody)
	}

	// return new response or error here
	return resp, err
}
Пример #10
0
// eccaProxy: proxy the user requests and authenticate with the credentials we know.
func eccaProxy(req *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
	//log.Println("\n\n\nRequest is ", req.Method, req.URL.String())
	ctx.Logf("Start-of-eccaProxy handler")
	for _, c := range req.Cookies() {
		ctx.Logf("Cookie send by the client is: %#v", c.Name)
	}

	// set the scheme to https so we connect upstream securely
	if req.URL.Scheme == "http" {
		req.URL.Scheme = "https"
	}

	// Copy the body because we need it untouched. But we also need to parse
	// the POST parameters and that eats the original buffer with the body
	body, err := ioutil.ReadAll(req.Body)
	check(err)
	req.Body.Close() // close it before replacing. Prevents leaking file descriptors.

	// give the data back immedeately.
	req.Body = ioutil.NopCloser(bytes.NewReader(body))

	// Read the parameters
	req.ParseForm()                                    // eats req.Body
	req.Body = ioutil.NopCloser(bytes.NewReader(body)) // copy back in again

	// Check for POST method with 'encrypt', 'sign' or 'initiate-direct-connection' parameter.
	if req.Method == "POST" {
		if req.Form.Get("initiate-direct-connection") == "required" {
			// create a direct connection listener, awaiting reply
			return initiateDirectConnection(req)
		} else if req.Form.Get("encrypt") == "required" {
			// transparantly encrypt and sign for a private message
			return encryptMessage(req)
		} else if req.Form.Get("sign") == "required" || req.Form.Get("sign") == "optional" {
			// transparently sign the message before publication
			return signMessage(req, ctx)
		}
	}

	// Fetch the request from upstream
	resp, err := fetchRequest(req, ctx)
	if err != nil {
		ctx.Warnf("There was an error fetching the users' request: %v", err)
		return req, goproxy.NewResponse(req,
			goproxy.ContentTypeText, http.StatusInternalServerError,
			"Some server error!")
	}

	ctx.Logf("response is %#v", resp)
	for _, c := range resp.Cookies() {
		ctx.Logf("Cookie send by the server is: %#v\n", c.Name)
	}
	ctx.Logf("End-of-eccaProxy handler")
	//log.Printf("Sleeping for 10 seconds...\n")
	//time.Sleep(10 * time.Second)
	return nil, resp // let goproxy send our response
}
Пример #11
0
// RoundTrip makes a request expecting a 401 response that will require digest
// authentication.  It creates the credentials it needs and makes a follow-up
// request.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	if t.Transport == nil {
		return nil, ErrNilTransport
	}

	// Hold on to the request body; a reader cannot be un-read.
	b, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return nil, err
	}

	// Copy the request so we don't modify the input.
	req2 := new(http.Request)
	*req2 = *req

	// Copying drains the request body. Set to body we saved above.
	req.Body = ioutil.NopCloser(bytes.NewReader(b))
	req2.Body = ioutil.NopCloser(bytes.NewReader(b))

	req2.Header = make(http.Header)
	for k, s := range req.Header {
		req2.Header[k] = s
	}

	// Make a request to get the 401 that contains the challenge.
	resp, err := t.Transport.RoundTrip(req)
	if err != nil || resp.StatusCode != 401 {
		return resp, err
	}
	// Read the response body, to enable the connection to be reused.
	_, err = io.Copy(ioutil.Discard, resp.Body)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	chal := resp.Header.Get("WWW-Authenticate")
	c, err := parseChallenge(chal)
	if err != nil {

		return resp, err
	}

	// Form credentials based on the challenge.
	cr := t.newCredentials(req2, c)
	auth, err := cr.authorize()
	if err != nil {
		return resp, err
	}

	// Make authenticated request.
	req2.Header.Set("Authorization", auth)
	return t.Transport.RoundTrip(req2)
}
Пример #12
0
// DumpRequestOut is like DumpRequest but includes
// headers that the standard http.Transport adds,
// such as User-Agent.
func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
	save := req.Body
	if !body || req.Body == nil {
		req.Body = nil
	} else {
		var err error
		save, req.Body, err = drainBody(req.Body)
		if err != nil {
			return nil, err
		}
	}

	// Since we're using the actual Transport code to write the request,
	// switch to http so the Transport doesn't try to do an SSL
	// negotiation with our dumpConn and its bytes.Buffer & pipe.
	// The wire format for https and http are the same, anyway.
	reqSend := req
	if req.URL.Scheme == "https" {
		reqSend = new(http.Request)
		*reqSend = *req
		reqSend.URL = new(url.URL)
		*reqSend.URL = *req.URL
		reqSend.URL.Scheme = "http"
	}

	// Use the actual Transport code to record what we would send
	// on the wire, but not using TCP.  Use a Transport with a
	// customer dialer that returns a fake net.Conn that waits
	// for the full input (and recording it), and then responds
	// with a dummy response.
	var buf bytes.Buffer // records the output
	pr, pw := io.Pipe()
	dr := &delegateReader{c: make(chan io.Reader)}
	// Wait for the request before replying with a dummy response:
	go func() {
		http.ReadRequest(bufio.NewReader(pr))
		dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\n\r\n")
	}()

	t := &http.Transport{
		Dial: func(net, addr string) (net.Conn, error) {
			return &dumpConn{io.MultiWriter(pw, &buf), dr}, nil
		},
	}

	_, err := t.RoundTrip(reqSend)

	req.Body = save
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
Пример #13
0
Файл: util.go Проект: htee/hteed
func CopyRequest(req *http.Request) *http.Request {
	outreq := new(http.Request)
	*outreq = *req // includes shallow copies of maps, but okay

	outreq.Proto = "HTTP/1.1"
	outreq.ProtoMajor = 1
	outreq.ProtoMinor = 1
	outreq.Close = false

	// Remove hop-by-hop headers to the backend.  Especially
	// important is "Connection" because we want a persistent
	// connection, regardless of what the client sent to us.  This
	// is modifying the same underlying map from req (shallow
	// copied above) so we only copy it if necessary.
	copiedHeaders := false
	for _, h := range hopHeaders {
		if outreq.Header.Get(h) != "" {
			if !copiedHeaders {
				outreq.Header = make(http.Header)
				copyHeader(outreq.Header, req.Header)
				copiedHeaders = true
			}
			outreq.Header.Del(h)
		}
	}

	if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
		// If we aren't the first proxy retain prior
		// X-Forwarded-For information as a comma+space
		// separated list and fold multiple headers into one.
		if prior, ok := outreq.Header["X-Forwarded-For"]; ok {
			clientIP = strings.Join(prior, ", ") + ", " + clientIP
		}
		outreq.Header.Set("X-Forwarded-For", clientIP)
	}

	// If the request body is not chunked, tee it into the
	// proxy request's body & and replace it with a buffered
	// copy of the request body (it will be fully read by
	// the proxy request).
	if !isChunked(req) {
		bodyBuffer := bytes.NewBuffer(make([]byte, 0, req.ContentLength))
		bodyReader := io.TeeReader(req.Body, bodyBuffer)

		outreq.Body = ioutil.NopCloser(bodyReader)
		req.Body = ioutil.NopCloser(bodyBuffer)
	} else {
		outreq.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
	}

	return outreq
}
Пример #14
0
Файл: request.go Проект: 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
}
Пример #15
0
//把request转换成[]byte,并且使body可以被再次读取
func MustRequestToStringCanRead(req *http.Request) (s string) {
	oldBody := req.Body
	defer oldBody.Close()
	body, err := ioutil.ReadAll(req.Body)
	if err != nil {
		panic(err)
	}
	req.Body = ioutil.NopCloser(bytes.NewReader(body))
	buf := &bytes.Buffer{}
	req.Write(buf)
	req.Body = ioutil.NopCloser(bytes.NewReader(body))
	return string(buf.Bytes())
}
Пример #16
0
// readRequest is like Read, but for HTTP request. Upon return, the body is
// replaced wit a buffer and can be read again.
func (srv *Server) readRequest(req *http.Request) ([]byte, error) {
	p, err := srv.read(req.Body, req.ContentLength)
	req.Body.Close()
	switch e := srv.uninstrument(err); {
	case e == io.EOF || e == io.ErrUnexpectedEOF || len(p) == 0:
		req.Body = ioutil.NopCloser(eofReader{})
		return nil, io.EOF
	case err != nil:
		return nil, err
	case len(p) != 0:
		req.Body = ioutil.NopCloser(bytes.NewReader(p))
	}
	return p, nil
}
Пример #17
0
// RoundTrip makes a request expecting a 401 response that will require digest
// authentication.  It creates the credentials it needs and makes a follow-up
// request.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	if t.Transport == nil {
		return nil, ErrNilTransport
	}

	// Copy the request so we don't modify the input.
	req2 := new(http.Request)
	*req2 = *req
	req2.Header = make(http.Header)
	for k, s := range req.Header {
		req2.Header[k] = s
	}
	// copy buf to resend it
	if req.Body != nil {
		buf, _ := ioutil.ReadAll(req.Body)
		req.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
		req2.Body = ioutil.NopCloser(bytes.NewBuffer(buf))
	}

	// Make a request to get the 401 that contains the challenge.
	resp, err := t.Transport.RoundTrip(req)
	if err != nil || resp.StatusCode != 401 {
		return resp, err
	}
	chal := resp.Header.Get("WWW-Authenticate")
	c, err := parseChallenge(chal)
	if err != nil {
		return resp, err
	}

	// Form credentials based on the challenge.
	cr := t.newCredentials(req2, c)
	auth, err := cr.authorize()
	if err != nil {
		return resp, err
	}

	// close response body to avoid goroutines leak
	if resp.Body != nil {
		resp.Body.Close()
	}
	// not sure about request body, but close it as well
	if req.Body != nil {
		req.Body.Close()
	}

	// Make authenticated request.
	req2.Header.Set("Authorization", auth)
	return t.Transport.RoundTrip(req2)
}
Пример #18
0
func (u *URL) Request(out interface{}, req *http.Request) error {
	var bodyBytes []byte
	var err error
	if req.Body != nil {
		bodyBytes, err = ioutil.ReadAll(req.Body)
		if err != nil {
			return err
		}
		req.Body = ioutil.NopCloser(bytes.NewReader(bodyBytes))
		if err != nil {
			return err
		}
	}

	r, err := makeRequest(req)
	if err != nil {
		return err
	}
	defer r.Body.Close()

	if r.StatusCode == 401 {
		if req.Body != nil {
			req.Body = ioutil.NopCloser(bytes.NewReader(bodyBytes))
		}
		r, err = promptAndAuth(r, req)
		if err != nil {
			return err
		}
	}

	var final error = nil
	if r.StatusCode != 200 {
		final = fmt.Errorf("Error %s", r.Status)
	}

	if out != nil {
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			return err
		}

		err = json.Unmarshal(body, out)
		if err != nil && final == nil {
			return err
		}
	}

	return final
}
Пример #19
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")
	}
}
Пример #20
0
// Prepares an *http.Request for doHttpRequest
func (s3 *S3) setupHttpRequest(req *request) (*http.Request, error) {
	u, err := req.url()
	if err != nil {
		return nil, err
	}
	u.Opaque = fmt.Sprintf("//%s%s", u.Host, partiallyEscapedPath(u.Path))

	hreq := http.Request{
		URL:        u,
		Method:     req.method,
		ProtoMajor: 1,
		ProtoMinor: 1,
		Close:      true,
		Header:     req.headers,
	}

	if v, ok := req.headers["Content-Length"]; ok {
		hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64)
		delete(req.headers, "Content-Length")
	}
	if req.payload != nil {
		hreq.Body = ioutil.NopCloser(req.payload)
	}

	return &hreq, nil
}
Пример #21
0
// signatureBase combines the uppercase request method, percent encoded base
// string URI, and parameter string. Returns the OAuth1 signature base string
// according to RFC5849 3.4.1.
// Does not mutate the Request or basicOAuthParams.
func signatureBase(req *http.Request, basicOAuthParams map[string]string) (string, error) {
	method := strings.ToUpper(req.Method)
	baseURL := strings.Split(req.URL.String(), "?")[0]
	// add oauth, query, and body parameters into params
	params := map[string]string{}
	for key, value := range req.URL.Query() {
		// most backends do not accept duplicate query keys
		params[key] = value[0]
	}
	if req.Body != nil && req.Header.Get(contentType) == formContentType {
		// reads data to a []byte, draining req.Body
		b, err := ioutil.ReadAll(req.Body)
		if err != nil {
			return "", err
		}
		values, err := url.ParseQuery(string(b))
		if err != nil {
			return "", err
		}
		for key, value := range values {
			params[key] = value[0]
		}
		// reinitialize Body with ReadCloser over the []byte
		req.Body = ioutil.NopCloser(bytes.NewReader(b))
	}
	for key, value := range basicOAuthParams {
		params[key] = value
	}
	// encode params into a parameter string (RFC5849 3.4.1.3, 3.4.1.3.2)
	parameterString := encodeParams(params)
	baseParts := []string{method, PercentEncode(baseURL), PercentEncode(parameterString)}
	return strings.Join(baseParts, "&"), nil
}
Пример #22
0
Файл: s3.go Проект: noah10/goamz
// Prepares an *http.Request for doHttpRequest
func (s3 *S3) setupHttpRequest(req *request) (*http.Request, error) {
	// Copy so that signing the http request will not mutate it
	headers := make(http.Header)
	for k, v := range req.headers {
		headers[k] = v
	}
	req.headers = headers

	u, err := req.url()
	if err != nil {
		return nil, err
	}
	u.Opaque = fmt.Sprintf("//%s%s", u.Host, partiallyEscapedPath(u.Path))

	hreq := http.Request{
		URL:        u,
		Method:     req.method,
		ProtoMajor: 1,
		ProtoMinor: 1,
		Close:      true,
		Header:     req.headers,
		Form:       req.params,
	}

	if v, ok := req.headers["Content-Length"]; ok {
		hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64)
		delete(req.headers, "Content-Length")
	}
	if req.payload != nil {
		hreq.Body = ioutil.NopCloser(req.payload)
	}

	return &hreq, nil
}
Пример #23
0
// ServeHTTP wraps the http.Request and http.ResponseWriter to log to standard
// output and pass through to the underlying http.Handler.
func (l *Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	requestID := l.RequestIDCreator(r)
	l.Printf(
		"%s > %s %s %s\n",
		requestID,
		r.Method,
		r.URL.RequestURI(),
		r.Proto,
	)
	for key, values := range r.Header {
		for _, value := range values {
			l.Printf("%s > %s: %s\n", requestID, key, value)
		}
	}
	l.Println(requestID, ">")
	r.Body = &readCloser{
		ReadCloser: r.Body,
		Logger:     l,
		requestID:  requestID,
	}
	l.handler.ServeHTTP(&loggerResponseWriter{
		ResponseWriter: w,
		Logger:         l,
		request:        r,
		requestID:      requestID,
	}, r)
}
Пример #24
0
func (rt *BackendRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
	var err error
	var res *http.Response
	var endpoint *route.Endpoint

	if request.Body != nil {
		closer := request.Body
		request.Body = ioutil.NopCloser(request.Body)
		defer func() {
			closer.Close()
		}()
	}

	for retry := 0; retry < handler.MaxRetries; retry++ {
		endpoint, err = rt.selectEndpoint(request)
		if err != nil {
			return nil, err
		}

		rt.setupRequest(request, endpoint)

		res, err = rt.transport.RoundTrip(request)
		if err == nil || !retryableError(err) {
			break
		}

		rt.reportError(err)
	}

	if rt.after != nil {
		rt.after(res, endpoint, err)
	}

	return res, err
}
Пример #25
0
// Prepares an *http.Request for doHttpRequest
func (s3 *S3) setupHttpRequest(req *request) (*http.Request, error) {
	u, err := req.url()
	if err != nil {
		return nil, err
	}

	hreq := http.Request{
		URL:        u,
		Host:       "s3.amazonaws.com",
		Method:     req.method,
		ProtoMajor: 1,
		ProtoMinor: 1,
		Close:      true,
		Header:     req.headers,
	}

	if v, ok := req.headers["Content-Length"]; ok {
		hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64)
		delete(req.headers, "Content-Length")
	}
	if req.payload != nil {
		hreq.Body = ioutil.NopCloser(req.payload)
	}

	return &hreq, nil
}
Пример #26
0
// NewMessage returns a new Message given a HTTP request, and an array of
// custom headers used in the HMAC signature generation.
func NewMessage(r *http.Request, headers ...[]string) *Message {

	h := NewHeaders()
	if len(headers) > 0 {
		for _, header := range headers[0] {
			h.Set(header, r.Header.Get(header))
		}
	}

	var body []byte = []byte{}
	if r.Body != nil {
		var err error
		body, err = ioutil.ReadAll(r.Body)
		if err != nil {
			return nil
		}
		r.Body.Close()
		copy := body[:]
		r.Body = ioutil.NopCloser(bytes.NewReader(copy))
	}

	return &Message{
		r.Method,
		HashData(body),
		r.Header.Get("Content-Type"),
		r.Header.Get("Date"),
		h,
		r.URL,
		true,
	}
}
Пример #27
0
func NewRequestDetailsFromHttpRequest(req *http.Request) (RequestDetails, error) {
	if req.Body == nil {
		req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte("")))
	}

	reqBody, err := extractRequestBody(req)

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"mode":  "capture",
		}).Error("Got error while reading request body")
		return RequestDetails{}, err
	}

	requestDetails := RequestDetails{
		Path:        req.URL.Path,
		Method:      req.Method,
		Destination: req.Host,
		Scheme:      req.URL.Scheme,
		Query:       req.URL.RawQuery,
		Body:        string(reqBody),
		Headers:     req.Header,
	}
	return requestDetails, nil
}
Пример #28
0
func authzViaPOST(r *http.Request, tok string) int {
	r.Method = "POST"
	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	r.Body = ioutil.NopCloser(strings.NewReader(
		url.Values{"api_token": {tok}}.Encode()))
	return http.StatusUnauthorized
}
Пример #29
0
func runHandler(resp http.ResponseWriter, req *http.Request,
	fn func(resp http.ResponseWriter, req *http.Request) error, errfn httputil.Error) {
	defer func() {
		if rv := recover(); rv != nil {
			err := errors.New("handler panic")
			logError(req, err, rv)
			errfn(resp, req, http.StatusInternalServerError, err)
		}
	}()

	if s := req.Header.Get("X-Real-Ip"); s != "" && httputil.StripPort(req.RemoteAddr) == "127.0.0.1" {
		req.RemoteAddr = s
	}

	req.Body = http.MaxBytesReader(resp, req.Body, 2048)
	req.ParseForm()
	var rb httputil.ResponseBuffer
	err := fn(&rb, req)
	if err == nil {
		rb.WriteTo(resp)
	} else if e, ok := err.(*httpError); ok {
		if e.status >= 500 {
			logError(req, err, nil)
		}
		errfn(resp, req, e.status, e.err)
	} else {
		logError(req, err, nil)
		errfn(resp, req, http.StatusInternalServerError, err)
	}
}
Пример #30
0
// also from goiardi calc and encodebody data
func calcBodyHash(r *http.Request) (string, error) {
	var bodyStr string
	var err error
	if r.Body == nil {
		bodyStr = ""
	} else {
		save := r.Body
		save, r.Body, err = drainBody(r.Body)
		if err != nil {
			return "", err
		}
		mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
		if err != nil {
			return "", err
		}
		if strings.HasPrefix(mediaType, "multipart/form-data") {
			bodyStr, err = readFileFromRequest(r, params["boundary"])
			if err != nil {
				return "", err
			}
		} else {
			buf := new(bytes.Buffer)
			buf.ReadFrom(r.Body)
			bodyStr = buf.String()
		}
		r.Body = save
	}
	chkHash := hashStr(bodyStr)
	return chkHash, err
}