Пример #1
0
func newRequest(hr *http.Request, hc http.ResponseWriter) *Request {

	remoteAddrIP, remotePort := hr.RemoteAddr, 0
	remoteAddr, _ := net.ResolveTCPAddr("tcp", hr.RemoteAddr)
	if remoteAddr != nil {
		remoteAddrIP = remoteAddr.IP.String()
		remotePort = remoteAddr.Port
	}

	req := Request{
		Method:     hr.Method,
		URL:        hr.URL,
		Proto:      hr.Proto,
		ProtoMajor: hr.ProtoMajor,
		ProtoMinor: hr.ProtoMinor,
		Headers:    hr.Header,
		Body:       hr.Body,
		Close:      hr.Close,
		Host:       hr.Host,
		Referer:    hr.Referer(),
		UserAgent:  hr.UserAgent(),
		FullParams: hr.Form,
		Cookie:     hr.Cookies(),
		RemoteAddr: remoteAddrIP,
		RemotePort: remotePort,
	}
	return &req
}
Пример #2
0
func referer(r *http.Request) (ref string) {
	ref = r.FormValue("ref")
	if len(ref) == 0 {
		ref = r.Referer()
		if len(ref) == 0 {
			ref = "/"
		}
	}
	return
}
Пример #3
0
// sent a request off to twitter. Returns the response's body or an error.
func send(url, method string, form map[string][]string, client *Client, body string) (result string, err os.Error) {
	req := new(http.Request)
	req.Method = method
	req.RawURL = url
	req.Host = URLHost
	req.Referer = "none"
	req.UserAgent = HTTPUserAgent
	req.Form = form
	req.Header = map[string]string{
		"Connection":    "Keep Alive",
		"Authorization": getAuthHeader(client),
	}
	req.Body = strings.NewReader(body)
	req.URL, err = http.ParseURL(req.RawURL)
	if err != nil {
		return "", err
	}

	// send request
	resp := new(http.Response)
	resp, err = http.Send(req)
	if err != nil {
		return "", err
	}
	result = getResponseBody(resp)
	return result, nil
}
Пример #4
0
// Forward a request to another domain
// By design Go doesn't let you define new methods on non-local types
func (this *HttpClient) Forward(req *http.Request, newDomain string) (resp *http.Response, err os.Error) {

	log.Printf("req host: %v\n", req.Host)
	// TODO change the the domain back
	for _, cookie := range req.Cookie {
		log.Printf("req cookie: %v\n", cookie)
	}

	var base *http.URL
	/*var r *http.Response*/
	url := (newDomain + req.URL.RawPath)
	log.Printf("forwarding to: " + url)

	redirectChecker := this.client.CheckRedirect
	if redirectChecker == nil {
		redirectChecker = defaultCheckRedirect
	}
	var via []*http.Request

	for redirect := 0; ; redirect++ {
		var nReq = http.Request{}
		nReq.Method = req.Method
		//log.Printf("HTTP method: " + nReq.Method)
		nReq.Header = req.Header
		//log.Printf("Headers: %v\n", nReq.Header)

		if base == nil {
			nReq.URL, err = http.ParseURL(url)
		} else {
			nReq.URL, err = base.ParseURL(url)
		}

		if err != nil {
			break
		}

		// Set the redirection referer headers
		if len(via) > 0 {
			// Add the Referer header.
			lastReq := via[len(via)-1]
			if lastReq.URL.Scheme != "https" {
				nReq.Referer = lastReq.URL.String()
			}

			err = redirectChecker(&nReq, via)
			if err != nil {
				break
			}
		}

		// TODO support for content in the body if we aren't
		// dealing with GET/HEAD requests.

		url = nReq.URL.String()
		// Wrapped the client so I could do that ...sigh...
		// Also, #Do i a wrapper around #send
		if resp, err = this.client.Do(&nReq); err != nil {
			break
		}

		if shouldRedirect(resp.StatusCode) {
			resp.Body.Close()
			if url = resp.Header.Get("Location"); url == "" {
				err = os.ErrorString(fmt.Sprintf("%d response missing Location header", resp.StatusCode))
				break
			}
			base = req.URL
			via = append(via, &nReq)
			continue
		}
		// log.Printf("final URL: " + url)

		return
	}

	err = &http.URLError{req.Method, url, err}
	return
}
Пример #5
0
// RequestFromMap creates an http.Request from CGI variables.
// The returned Request's Body field is not populated.
func RequestFromMap(params map[string]string) (*http.Request, os.Error) {
	r := new(http.Request)
	r.Method = params["REQUEST_METHOD"]
	if r.Method == "" {
		return nil, os.NewError("cgi: no REQUEST_METHOD in environment")
	}

	r.Proto = params["SERVER_PROTOCOL"]
	var ok bool
	r.ProtoMajor, r.ProtoMinor, ok = http.ParseHTTPVersion(r.Proto)
	if !ok {
		return nil, os.NewError("cgi: invalid SERVER_PROTOCOL version")
	}

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

	r.Host = params["HTTP_HOST"]
	r.Referer = params["HTTP_REFERER"]
	r.UserAgent = params["HTTP_USER_AGENT"]

	if lenstr := params["CONTENT_LENGTH"]; lenstr != "" {
		clen, err := strconv.Atoi64(lenstr)
		if err != nil {
			return nil, os.NewError("cgi: bad CONTENT_LENGTH in environment: " + lenstr)
		}
		r.ContentLength = clen
	}

	if ct := params["CONTENT_TYPE"]; ct != "" {
		r.Header.Set("Content-Type", ct)
	}

	// Copy "HTTP_FOO_BAR" variables to "Foo-Bar" Headers
	for k, v := range params {
		if !strings.HasPrefix(k, "HTTP_") || skipHeader[k] {
			continue
		}
		r.Header.Add(strings.Replace(k[5:], "_", "-", -1), v)
	}

	// TODO: cookies.  parsing them isn't exported, though.

	if r.Host != "" {
		// Hostname is provided, so we can reasonably construct a URL,
		// even if we have to assume 'http' for the scheme.
		r.RawURL = "http://" + r.Host + params["REQUEST_URI"]
		url, err := http.ParseURL(r.RawURL)
		if err != nil {
			return nil, os.NewError("cgi: failed to parse host and REQUEST_URI into a URL: " + r.RawURL)
		}
		r.URL = url
	}
	// Fallback logic if we don't have a Host header or the URL
	// failed to parse
	if r.URL == nil {
		r.RawURL = params["REQUEST_URI"]
		url, err := http.ParseURL(r.RawURL)
		if err != nil {
			return nil, os.NewError("cgi: failed to parse REQUEST_URI into a URL: " + r.RawURL)
		}
		r.URL = url
	}

	// There's apparently a de-facto standard for this.
	// http://docstore.mik.ua/orelly/linux/cgi/ch03_02.htm#ch03-35636
	if s := params["HTTPS"]; s == "on" || s == "ON" || s == "1" {
		r.TLS = &tls.ConnectionState{HandshakeComplete: true}
	}

	// Request.RemoteAddr has its port set by Go's standard http
	// server, so we do here too. We don't have one, though, so we
	// use a dummy one.
	r.RemoteAddr = net.JoinHostPort(params["REMOTE_ADDR"], "0")

	return r, nil
}
Пример #6
0
func requestFromEnvironment(env map[string]string) (*http.Request, os.Error) {
	r := new(http.Request)
	r.Method = env["REQUEST_METHOD"]
	if r.Method == "" {
		return nil, os.NewError("cgi: no REQUEST_METHOD in environment")
	}
	r.Close = true
	r.Trailer = http.Header{}
	r.Header = http.Header{}

	r.Host = env["HTTP_HOST"]
	r.Referer = env["HTTP_REFERER"]
	r.UserAgent = env["HTTP_USER_AGENT"]

	// CGI doesn't allow chunked requests, so these should all be accurate:
	r.Proto = "HTTP/1.0"
	r.ProtoMajor = 1
	r.ProtoMinor = 0
	r.TransferEncoding = nil

	if lenstr := env["CONTENT_LENGTH"]; lenstr != "" {
		clen, err := strconv.Atoi64(lenstr)
		if err != nil {
			return nil, os.NewError("cgi: bad CONTENT_LENGTH in environment: " + lenstr)
		}
		r.ContentLength = clen
		r.Body = ioutil.NopCloser(io.LimitReader(os.Stdin, clen))
	}

	// Copy "HTTP_FOO_BAR" variables to "Foo-Bar" Headers
	for k, v := range env {
		if !strings.HasPrefix(k, "HTTP_") || skipHeader[k] {
			continue
		}
		r.Header.Add(strings.Replace(k[5:], "_", "-", -1), v)
	}

	// TODO: cookies.  parsing them isn't exported, though.

	if r.Host != "" {
		// Hostname is provided, so we can reasonably construct a URL,
		// even if we have to assume 'http' for the scheme.
		r.RawURL = "http://" + r.Host + env["REQUEST_URI"]
		url, err := http.ParseURL(r.RawURL)
		if err != nil {
			return nil, os.NewError("cgi: failed to parse host and REQUEST_URI into a URL: " + r.RawURL)
		}
		r.URL = url
	}
	// Fallback logic if we don't have a Host header or the URL
	// failed to parse
	if r.URL == nil {
		r.RawURL = env["REQUEST_URI"]
		url, err := http.ParseURL(r.RawURL)
		if err != nil {
			return nil, os.NewError("cgi: failed to parse REQUEST_URI into a URL: " + r.RawURL)
		}
		r.URL = url
	}
	return r, nil
}
Пример #7
-1
func (h *logHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
	// Strip port number from address
	addr := r.RemoteAddr
	if colon := strings.LastIndex(addr, ":"); colon != -1 {
		addr = addr[:colon]
	}

	lr := &logRecord{
		time:           time.UTC(),
		ip:             addr,
		method:         r.Method,
		rawpath:        r.URL.RawPath,
		userAgent:      r.UserAgent(),
		referer:        r.Referer(),
		responseStatus: http.StatusOK,
		proto:          r.Proto,
		ResponseWriter: rw,
	}
	h.handler.ServeHTTP(lr, r)
	h.ch <- lr
}