示例#1
0
	"github.com/garyburd/twister/web"
	"reflect"
	"testing"
)

type parseTest struct {
	name    string
	method  string
	url     string
	version int
	header  web.StringsMap
	s       string
}

var parseTests = []parseTest{
	parseTest{"no body", "", "", 0, web.NewStringsMap(), "GET /foo HTTP/1.1\r\n"},
	parseTest{"empty", "", "", 0, web.NewStringsMap(), " "},
	parseTest{"simple", "GET", "/foo", web.ProtocolVersion(1, 1), web.NewStringsMap(),
		`GET /foo HTTP/1.1

`},
	parseTest{"multihdr", "GET", "/foo", web.ProtocolVersion(1, 0), web.NewStringsMap(
		web.HeaderContentType, "text/html",
		web.HeaderCookie, "hello=world",
		web.HeaderCookie, "foo=bar"),
		`GET /foo HTTP/1.0
Content-Type: text/html
CoOkie: hello=world
Cookie: foo=bar

`},
示例#2
0
func (ts *TwitterStream) connect() {
	var err os.Error
	log.Println("twitterstream: connecting to", ts.url)

	url, err := http.ParseURL(ts.url)
	if err != nil {
		panic("bad url: " + ts.url)
	}

	addr := url.Host
	if strings.LastIndex(addr, ":") <= strings.LastIndex(addr, "]") {
		if url.Scheme == "http" {
			addr = addr + ":80"
		} else {
			addr = addr + ":443"
		}
	}

	param := web.StringsMap{}
	for key, values := range ts.param {
		param[key] = values
	}
	ts.oauthClient.SignParam(ts.accessToken, "POST", ts.url, param)

	body := param.FormEncodedBytes()

	header := web.NewStringsMap(
		web.HeaderHost, url.Host,
		web.HeaderConnection, "close", // disable chunk encoding in response
		web.HeaderContentLength, strconv.Itoa(len(body)),
		web.HeaderContentType, "application/x-www-form-urlencoded")

	var request bytes.Buffer
	request.WriteString("POST ")
	request.WriteString(url.RawPath)
	request.WriteString(" HTTP/1.1\r\n")
	header.WriteHttpHeader(&request)
	request.Write(body)

	proxyURL, _ := http.ParseURL(os.Getenv("HTTP_PROXY"))

	if url.Scheme == "http" {
		if proxyURL != nil {
			ts.conn, err = net.Dial("tcp", "", proxyURL.Host)
		} else {
			ts.conn, err = net.Dial("tcp", "", addr)
		}
		if err != nil {
			ts.error("dial failed ", err)
			return
		}
	} else {
		if proxyURL != nil {
			var proxyConn net.Conn
			proxyConn, err = net.Dial("tcp", "", proxyURL.Host)
			if err == nil {
				ts.conn = tls.Client(proxyConn, nil)
				proxyConn.Write([]byte("CONNECT " + addr + " HTTP/1.1\r\n\r\n"))
				b := make([]byte, 1024)
				proxyConn.Read(b)
			}
		} else {
			ts.conn, err = tls.Dial("tcp", "", addr, nil)
		}
		if err != nil {
			ts.error("dial failed ", err)
			return
		}
		if err = ts.conn.(*tls.Conn).VerifyHostname(addr[:strings.LastIndex(addr, ":")]); err != nil {
			ts.error("could not verify host", err)
			return
		}
	}

	// Set timeout to detect dead connection. Twitter sends at least one line
	// to the response every 30 seconds.
	err = ts.conn.SetReadTimeout(60e9)
	if err != nil {
		ts.error("set read timeout failed", err)
		return
	}

	if _, err := ts.conn.Write(request.Bytes()); err != nil {
		ts.error("error writing request: ", err)
		return
	}

	ts.r, _ = bufio.NewReaderSize(ts.conn, 8192)
	p, err := ts.r.ReadSlice('\n')
	if err != nil {
		ts.error("error reading response: ", err)
		return
	}

	m := responseLineRegexp.FindSubmatch(p)
	if m == nil {
		ts.error("bad response line", nil)
		return
	}

	for {
		p, err = ts.r.ReadSlice('\n')
		if err != nil {
			ts.error("error reading header: ", err)
			return
		}
		if len(p) <= 2 {
			break
		}
	}

	if string(m[1]) != "200" {
		p, _ := ioutil.ReadAll(ts.r)
		log.Println(string(p))
		ts.error("bad response code: "+string(m[1]), nil)
		return
	}

	log.Println("twitterstream: connected to", ts.url)
}