Exemple #1
1
func (conn *streamConn) connect() (*http.Response, os.Error) {
	if conn.stale {
		return nil, os.NewError("Stale connection")
	}
	tcpConn, err := net.Dial("tcp", "", conn.url.Host+":80")
	if err != nil {
		return nil, err
	}
	conn.clientConn = http.NewClientConn(tcpConn, nil)

	var req http.Request
	req.URL = conn.url
	req.Method = "GET"
	req.Header = map[string]string{}
	req.Header["Authorization"] = "Basic " + conn.authData

	if conn.postData != "" {
		req.Method = "POST"
		req.Body = nopCloser{bytes.NewBufferString(conn.postData)}
		req.ContentLength = int64(len(conn.postData))
		req.Header["Content-Type"] = "application/x-www-form-urlencoded"
	}

	err = conn.clientConn.Write(&req)
	if err != nil {
		return nil, err
	}

	resp, err := conn.clientConn.Read()
	if err != nil {
		return nil, err
	}

	return resp, nil
}
Exemple #2
1
func ReadFrom(conn net.Conn, method string) (resp *http.Response, e os.Error) {
	// Read from and proccess the connection
	req := new(http.Request)
	req.Method = method

	reader := bufio.NewReader(conn)
	resp, e = http.ReadResponse(reader, req)
	if e != nil {
		fmt.Println("Error reading response:", e)
	}
	return
}
Exemple #3
0
// Perform a GET request for the test t.
func Get(t *Test) (r *http.Response, finalUrl string, cookies []*http.Cookie, err os.Error) {
	var url = t.Url // <-- Patched

	var req http.Request
	req.Method = "GET"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Header = http.Header{}

	if len(t.Param) > 0 {
		ep := http.EncodeQuery(t.Param)
		if strings.Contains(url, "?") {
			url = url + "&" + ep
		} else {
			url = url + "?" + ep
		}
	}
	req.URL, err = http.ParseURL(url)
	if err != nil {
		err = &http.URLError{"Get", url, err}
		return
	}

	addHeadersAndCookies(&req, t)
	url = req.URL.String()
	debug("Will get from %s", req.URL.String())
	r, finalUrl, cookies, err = DoAndFollow(&req, t.Dump)
	return
}
Exemple #4
0
func NewRequest(method string, url string, doc IDocument) *http.Request {
	var req http.Request
	req.Method = method
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	req.Header = map[string]string{
		"Content-Type":    "application/json",
		"X-Riak-ClientId": "riak.go",
	}
	if doc.VectorClock() != "" {
		req.Header["X-Riak-Vclock"] = doc.VectorClock()
	}
	req.TransferEncoding = []string{"chunked"}
	req.URL, _ = http.ParseURL(url)

	if doc.Json() != "" {
		cb := &ClosingBuffer{bytes.NewBufferString(doc.Json())}
		var rc io.ReadCloser
		rc = cb
		req.Body = rc
	}
	fmt.Println(req.URL)
	return &req
}
Exemple #5
0
func Delete(url string) *HttpRequestBuilder {
	var req http.Request
	req.Method = "DELETE"
	req.Header = http.Header{}
	req.Header.Set("User-Agent", defaultUserAgent)
	return &HttpRequestBuilder{url, &req, nil, map[string]string{}}
}
// 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
}
Exemple #7
0
func post(theUrl string, oauthHeaders map[string]string) (r *http.Response, err os.Error) {
	var req http.Request
	var authorization string = "OAuth "
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	req.Header = http.Header{}

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

	first := true
	for k, v := range oauthHeaders {
		if first {
			first = false
		} else {
			authorization += ",\n    "
		}
		authorization += k + "=\"" + v + "\""
	}

	req.Header.Add("Authorization", authorization)

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

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

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

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

	return send(&req)
}
Exemple #9
0
func (c *Consumer) httpExecute(
	method string, url string, body string, oauthParams *OrderedParams) (*http.Response, os.Error) {

	if c.debug {
		fmt.Println("httpExecute(method: " + method + ", url: " + url)
	}

	var req http.Request
	req.Method = method
	req.Header = http.Header{}
	req.Body = newStringReadCloser(body)
	parsedurl, err := http.ParseURL(url)
	if err != nil {
		return nil, os.NewError("ParseUrl: " + err.String())
	}
	req.URL = parsedurl

	oauthHdr := "OAuth "
	for pos, key := range oauthParams.Keys() {
		if pos > 0 {
			oauthHdr += ","
		}
		oauthHdr += key + "=\"" + oauthParams.Get(key) + "\""
	}
	if c.debug {
		fmt.Println("AUTH-HDR: " + oauthHdr)
	}
	req.Header.Add("Authorization", oauthHdr)

	resp, err := c.HttpClient.Do(&req)

	if err != nil {
		return nil, os.NewError("Do: " + err.String())
	}

	debugHeader := ""
	for k, vals := range req.Header {
		for _, val := range vals {
			debugHeader += "[key: " + k + ", val: " + val + "]"
		}
	}

	if resp.StatusCode != http.StatusOK {
		bytes, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()

		return nil, os.NewError("HTTP response is not 200/OK as expected. Actual response: \n" +
			"\tResponse Status: '" + resp.Status + "'\n" +
			"\tResponse Code: " + strconv.Itoa(resp.StatusCode) + "\n" +
			"\tResponse Body: " + string(bytes) + "\n" +
			"\tRequst Headers: " + debugHeader)
	}
	return resp, err
}
Exemple #10
0
func sendBody(s Sender, url, method, bodyType string, body io.Reader) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = method
	req.RawURL = url
	req.Body = nopCloser{body}
	req.Header = map[string]string{
		"Content-Type": bodyType,
	}
	req.TransferEncoding = []string{"chunked"}
	return Send(s, &req)
}
Exemple #11
0
func (conn *streamConn) connect() (*http.Response, os.Error) {
	if conn.stale {
		return nil, os.NewError("Stale connection")
	}
	var tcpConn net.Conn
	var err os.Error
	if proxy := os.Getenv("HTTP_PROXY"); len(proxy) > 0 {
		proxy_url, _ := url.Parse(proxy)
		tcpConn, err = net.Dial("tcp", proxy_url.Host)
	} else {
		tcpConn, err = net.Dial("tcp", conn.url.Host+":443")
	}
	if err != nil {
		return nil, err
	}
	cf := &tls.Config{Rand: rand.Reader, Time: time.Nanoseconds}
	ssl := tls.Client(tcpConn, cf)

	conn.clientConn = http.NewClientConn(ssl, nil)

	var req http.Request
	req.URL = conn.url
	req.Method = "GET"
	req.Header = http.Header{}
	req.Header.Set("Authorization", "Basic "+conn.authData)

	if conn.postData != "" {
		req.Method = "POST"
		req.Body = nopCloser{bytes.NewBufferString(conn.postData)}
		req.ContentLength = int64(len(conn.postData))
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}

	resp, err := conn.clientConn.Do(&req)
	if err != nil {
		return nil, err
	}

	return resp, nil
}
Exemple #12
0
func authGet(url, user, pwd string) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = "GET"
	req.Header = map[string][]string{"Authorization": {"Basic " +
		encodedUsernameAndPassword(user, pwd)}}
	if req.URL, err = http.ParseURL(url); err != nil {
		return
	}
	if r, err = send(&req); err != nil {
		return
	}
	return
}
Exemple #13
0
// Delete issues a DELETE to the specified URL.
func authDelete(url, user, pwd string) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = "DELETE"
	if user != "" && pwd != "" {
		req.Header = map[string]string{"Authorization": "Basic " +
			encodedUsernameAndPassword(user, pwd)}
	}
	if req.URL, err = http.ParseURL(url); err != nil {
		return
	}
	if r, err = send(&req); err != nil {
		return
	}
	return
}
Exemple #14
0
// Serves the HTTP request and writes the response to the specified writer
func (handler *HttpHandler) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {

	var route *Route
	var found bool = false
	var context *Context

	// we always need the form parsing
	request.ParseForm()

	// do we need to spoof the HTTP method?
	overrideMethod := request.Form.Get(REQUEST_METHOD_OVERRIDE_PARAMETER)
	if overrideMethod != "" {
		request.Method = strings.ToUpper(overrideMethod)
	}

	// get the matching route
	found, route, context = handler.GetMathingRoute(responseWriter, request)

	if !found {

		// no route found - this is an error

		// create the request context (with no parameter keys obviously)
		context = makeContext(request, responseWriter, nil)

		error := os.NewError(ERR_NO_MATCHING_ROUTE)
		handler.HandleError(context, error)

	} else {

		// tell the controller to handle the route
		var controller Controller = route.Controller

		// make sure we have a controller
		if controller == nil {

			error := os.NewError(ERR_NO_CONTROLLER)
			handler.HandleError(context, error)

		} else {
			controller.HandleRequest(context)
		}

	}

}
Exemple #15
0
func HttpGet(url string) (*http.Response, os.Error) {
	var r *http.Response
	var err os.Error
	if proxy := os.Getenv("HTTP_PROXY"); len(proxy) > 0 {
		proxy_url, _ := http.ParseURL(proxy)
		tcp, _ := net.Dial("tcp", "", proxy_url.Host)
		conn := http.NewClientConn(tcp, nil)
		var req http.Request
		req.URL, _ = http.ParseURL(url)
		req.Method = "GET"
		err = conn.Write(&req)
		r, err = conn.Read()
	} else {
		r, _, err = http.Get(url)
	}
	return r, err
}
// This function is launched async as a go routine. It tries to send a message
// to a remote server and sends a bool to nextChannel to indicate whether this
// has succeeded or not. It is not allowed to run this function multiple times in parallel
// for the same FederationGateway.
func (self *FederationGateway) sendFromQueue(req *WaveletUpdateRequest) {
	// No HTTP connection open yet?
	if self.connection == nil {
		con, err := net.Dial("tcp", "", fmt.Sprintf("%v:%v", self.manifest.HostName, self.manifest.Port))
		if err != nil {
			// TODO: Good error handling
			log.Println("Failed connecting to ", self.manifest, err)
			self.nextChannel <- false
			return
		}
		self.connection = http.NewClientConn(con, nil)
	}

	// Build the HTTP request
	var hreq http.Request
	hreq.Host = self.manifest.Domain
	hreq.Header = make(map[string]string)
	hreq.RawURL = fmt.Sprintf("http://%v:%v/fed%v", self.manifest.HostName, self.manifest.Port, req.uri)
	hreq.Method = "PUT"
	hreq.Body = NewRequestBody(req.Data)
	hreq.ContentLength = int64(len(req.Data))
	hreq.Header["Content-Type"] = req.MimeType
	log.Println("Sending WaveletUpdate to remote server ", hreq.RawURL)

	// Send the HTTP request
	self.connection.Write(&hreq)
	// Read the HTTP response
	hres, err := self.connection.Read()
	if err != nil {
		log.Println("Error reading HTTP response from ", self.manifest, err)
		// TODO: Better error handling
		self.connection.Close()
		self.connection = nil
		self.nextChannel <- false
		return
	}

	log.Println("After sending WaveletUpdate, status code is ", hres.StatusCode)
	// Success in sending the wavelet update?
	if hres.StatusCode == 200 {
		self.nextChannel <- true
		return
	}
	// Sending the wavelet update failed
	self.nextChannel <- false
}
Exemple #17
0
func YadisRequest(url_ string, method string) (resp *http.Response, err os.Error) {
	resp = nil

	var request = new(http.Request)
	var client = new(http.Client)
	var Header = make(http.Header)

	request.Method = method
	request.RawURL = url_

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

	// Common parameters
	request.Proto = "HTTP/1.0"
	request.ProtoMajor = 1
	request.ProtoMinor = 0
	request.ContentLength = 0
	request.Close = true

	Header.Add("Accept", "application/xrds+xml")
	request.Header = Header

	// Follow a maximum of 5 redirections
	for i := 0; i < 5; i++ {
		response, err := client.Do(request)

		if err != nil {
			return nil, err
		}
		if response.StatusCode == 301 || response.StatusCode == 302 || response.StatusCode == 303 || response.StatusCode == 307 {
			location := response.Header.Get("Location")
			request.RawURL = location
			request.URL, err = url.Parse(location)
			if err != nil {
				return
			}
		} else {
			return response, nil
		}
	}
	return nil, os.NewError("Too many redirections")
}
Exemple #18
0
func nmcPOST(body *bytes.Buffer) (response *http.Response, err os.Error) {
	client := http.Client{}

	var req http.Request
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	req.Body = ioutil.NopCloser(body)
	req.Header = http.Header{
		"Content-Type":   []string{"text/plain"},
		"Content-Length": []string{strconv.Itoa(body.Len())},
	}
	req.ContentLength = int64(body.Len())
	req.URL = options.nmcURL

	return client.Do(&req)
}
Exemple #19
0
// General Request method used by the specialized request methods to create a request
func (client *Client) newRequest(method string, id string) (*http.Request, os.Error) {
	request := new(http.Request)
	var err os.Error

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

	request.Method = method

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

	return request, nil
}
Exemple #20
0
// post taken from Golang modified to allow Headers to be pased
func post(url string, headers map[string]string, body io.Reader) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	req.Body = nopCloser{body}
	for k, v := range headers {
		req.Header.Add(k, v)
	}
	req.TransferEncoding = []string{"chunked"}

	req.URL, err = http.ParseURL(url)
	if err != nil {
		return nil, err
	}

	return send(&req)
}
Exemple #21
0
// Post issues a POST to the specified URL.
//
// Caller should close r.Body when done reading it.
func Post(url, user, pwd, bodyType string, body io.Reader) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = "POST"
	req.Body = nopCloser{body}
	req.Header = map[string]string{
		"Content-Type":      bodyType,
		"Transfer-Encoding": "chunked",
		"X-Twitter-Client":  "gotweet",
		"X-Twitter-Version": "0.1",
		"Authorization":     "Basic " + encodedUsernameAndPassword(user, pwd),
	}

	req.URL, err = http.ParseURL(url)
	if err != nil {
		return nil, err
	}

	return send(&req)
}
Exemple #22
0
// Post issues a POST to the specified URL.
//
// Caller should close r.Body when done reading it.
func authPost(url, user, pwd, client, clientURL, version, agent, bodyType string,
	body io.Reader) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = "POST"
	req.Body = body.(io.ReadCloser)
	req.Header = map[string]string{
		"Content-Type":         bodyType,
		"Transfer-Encoding":    "chunked",
		"User-Agent":           agent,
		"X-FluidDB-Client":     client,
		"X-FluidDB-Client-URL": clientURL,
		"X-FluidDB-Version":    version,
		"Authorization":        "Basic " + encodedUsernameAndPassword(user, pwd),
	}

	req.URL, err = http.ParseURL(url)
	if err != nil {
		return nil, err
	}

	return send(&req)
}
Exemple #23
0
func main() {

	url, err := http.ParseURL("http://bbs.golang-china.org/")

	if err != nil {
		log.Exit(err)
	}

	tcpConn, err := net.Dial("tcp", "", url.Host+":80")

	if err != nil {
		log.Exit(err)
	}

	clientConn := http.NewClientConn(tcpConn, nil)

	var req http.Request
	req.URL = url
	req.Method = "GET"
	req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.11 (KHTML, like Gecko) Chrome/9.0.570.0 Safari/534.11"
	req.Header = map[string]string{}
	req.Header["Connection"] = "keep-alive"

	err = clientConn.Write(&req)
	if err != nil {
		log.Exit(err)
	}
	resp, err := clientConn.Read()
	if err != nil {
		log.Exit(err)
	}
	defer resp.Body.Close()

	log.Println("Http Response: " + resp.Status)
	body, _ := ioutil.ReadAll(resp.Body)

	log.Println(string(body))
}
Exemple #24
0
func GetManifest(host string, port uint16) *ServerManifest {
	log.Println("Discovery at ", host, port)
	// Make a TCP connection
	con, err := net.Dial("tcp", "", fmt.Sprintf("%v:%v", host, port))
	if err != nil {
		log.Println("Failed connecting to ", host, port, err)
		return nil
	}
	// Make a HTTP connection
	hcon := http.NewClientConn(con, nil)
	// Build the HTTP request
	var hreq http.Request
	hreq.Host = host
	hreq.Method = "GET"
	hreq.RawURL = fmt.Sprintf("http://%v:%v/_manifest", host, port)
	log.Println("Sending request")
	// Send the HTTP request
	if err = hcon.Write(&hreq); err != nil {
		log.Println("Error sending GET request")
		hcon.Close()
		return nil
	}
	// Read the HTTP response
	_, err = hcon.Read()
	if err != nil {
		log.Println("Error reading HTTP response from ", host, err)
		hcon.Close()
		return nil
	}

	m := &ServerManifest{}
	// TODO: Parse the manifest
	// HACK START
	m.HostName = host
	m.Port = port
	// HACK END
	return m
}
Exemple #25
0
// Post issues a POST to the specified URL.
//
// Caller should close r.Body when done reading it.
func authPost(url, user, pwd, client, clientURL, version, agent, bodyType string,
	body io.Reader) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = "POST"
	req.Body = body.(io.ReadCloser)

	h := make(http.Header)
	h.Add("Content-Type", bodyType)
	h.Add("Transfer-Encoding", "chunked")
	h.Add("User-Agent", agent)
	h.Add("X-Twitter-Client", client)
	h.Add("X-Twitter-Client-URL", clientURL)
	h.Add("X-Twitter-Version", version)
	h.Add("Authorization", "Basic "+encodedUsernameAndPassword(user, pwd))
	req.Header = h

	req.URL, err = http.ParseURL(url)
	if err != nil {
		return nil, err
	}

	return send(&req)
}
Exemple #26
0
// PostForm issues a POST to the specified URL,
// with data's keys and values urlencoded as the request body.
//
// Caller should close r.Body when done reading from it.
func Post(t *Test) (r *http.Response, finalUrl string, cookies []*http.Cookie, err os.Error) {
	var req http.Request
	var url = t.Url
	req.Method = "POST"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Close = true
	var body *bytes.Buffer
	var contentType string
	if hasFile(&t.Param) || t.Method == "POST:mp" {
		var boundary string
		body, boundary = multipartBody(&t.Param)
		contentType = "multipart/form-data; boundary=" + boundary
	} else {
		contentType = "application/x-www-form-urlencoded"
		bodystr := http.EncodeQuery(t.Param)
		body = bytes.NewBuffer([]byte(bodystr))
	}

	req.Body = nopCloser{body}
	req.Header = http.Header{
		"Content-Type":   {contentType},
		"Content-Length": {strconv.Itoa(body.Len())},
	}
	addHeadersAndCookies(&req, t)

	req.ContentLength = int64(body.Len())
	req.URL, err = http.ParseURL(url)
	if err != nil {
		return nil, url, cookies, err
	}
	debug("Will post to %s", req.URL.String())

	r, finalUrl, cookies, err = DoAndFollow(&req, t.Dump)
	return
}
// 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
}
Exemple #28
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
}
Exemple #29
0
// Perform the request and follow up to 10 redirects.
// All cookie setting are collected, the final URL is reported.
func DoAndFollow(req *http.Request, dump io.Writer) (response *http.Response, finalUrl string, cookies []*http.Cookie, err os.Error) {
	// TODO: set referrer header on redirects.

	// Move User-Agent from Header to Request
	if ua := req.Header.Get("User-Agent"); ua != "" {
		req.UserAgent = ua
		req.Header.Del("User-Agent")
	}

	info("%s %s", req.Method, req.URL.String())
	dumpReq(req, dump)
	response, err = http.DefaultClient.Do(req)
	if err != nil {
		return
	}
	dumpRes(response, dump)

	finalUrl = req.URL.String()
	cookies = updateCookies(cookies, response.SetCookie)
	req.Cookie = updateCookies(req.Cookie, response.SetCookie)

	if !shouldRedirect(response.StatusCode) {
		return
	}

	// Start redirecting to final destination
	response.Body.Close()
	var base = req.URL

	// Following the redirect chain is done with a cleaned/empty GET request.
	req.Method = "GET"
	req.ProtoMajor = 1
	req.ProtoMinor = 1
	req.Header.Del("Content-Type")
	req.Header.Del("Content-Length")
	req.Header.Del("Accept-Encoding")
	req.Header.Del("Connection")
	req.Body = nil
	for redirect := 0; redirect < 10; redirect++ {
		var url string

		if url = response.Header.Get("Location"); url == "" {
			fmt.Printf("Header:\n%v", response.Header)
			err = os.ErrorString(fmt.Sprintf("%d response missing Location header", response.StatusCode))
			return
		}
		if base == nil {
			req.URL, err = http.ParseURL(url)
		} else {
			req.URL, err = base.ParseURL(url)
		}
		if err != nil {
			return
		}

		url = req.URL.String()
		info("GET %s", url)
		dumpReq(req, dump)

		if response, err = http.DefaultClient.Do(req); err != nil {
			return
		}

		dumpRes(response, dump)
		finalUrl = url
		cookies = updateCookies(cookies, response.SetCookie)
		req.Cookie = updateCookies(req.Cookie, response.SetCookie)

		if !shouldRedirect(response.StatusCode) {
			return
		}
		response.Body.Close()
		base = req.URL

	}
	err = os.ErrorString("Too many redirects.")
	return
}
Exemple #30
-1
// Put issues a PUT to the specified URL.
//
// Caller should close r.Body when done reading it.
func authPut(url, user, pwd, client, clientURL, version, agent, bodyType string,
	body io.Reader) (r *http.Response, err os.Error) {
	var req http.Request
	req.Method = "PUT"
	req.Body = body.(io.ReadCloser)
	if user != "" && pwd != "" {
		req.Header = map[string][]string{
			"Content-Type":         {bodyType},
			"Transfer-Encoding":    {"chunked"},
			"User-Agent":           {agent},
			"X-FluidDB-Client":     {client},
			"X-FluidDB-Client-URL": {clientURL},
			"X-FluidDB-Version":    {version},
			"Authorization":        {"Basic " + encodedUsernameAndPassword(user, pwd)},
		}
	} else {
		req.Header = map[string][]string{
			"Content-Type":         {bodyType},
			"Transfer-Encoding":    {"chunked"},
			"User-Agent":           {agent},
			"X-FluidDB-Client":     {client},
			"X-FluidDB-Client-URL": {clientURL},
			"X-FluidDB-Version":    {version},
		}
	}

	req.URL, err = http.ParseURL(url)
	if err != nil {
		return nil, err
	}

	return send(&req)
}