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