func send(req *http.Request) (resp *http.Response, err os.Error) { addr := req.URL.Host if !hasPort(addr) { addr += ":http" } conn, err := net.Dial("tcp", addr) if err != nil { return nil, err } err = req.Write(conn) if err != nil { conn.Close() return nil, err } reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, req.Method) if err != nil { conn.Close() return nil, err } r := io.Reader(reader) if n := resp.ContentLength; n != -1 { r = io.LimitReader(r, n) } resp.Body = readClose{r, conn} return }
func (t *logTransport) RoundTrip(req *http.Request) (*http.Response, os.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 }
func send(req *http.Request) (resp *http.Response, err os.Error) { addr := req.URL.Host if !hasPort(addr) { addr += ":http" } conn, err := net.Dial("tcp", "", addr) if err != nil { return nil, err } err = req.Write(conn) if err != nil { conn.Close() return nil, err } reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, "GET") if err != nil { conn.Close() return nil, err } r := io.Reader(reader) if v := resp.GetHeader("Content-Length"); v != "" { n, err := strconv.Atoi64(v) if err != nil { // return nil, &badStringError{"invalid Content-Length", v} } r = io.LimitReader(r, n) } resp.Body = readClose{r, conn} return }
// execute a request; date it, sign it, send it func (bucket *Bucket) Execute(req *http.Request) (resp *http.Response, err os.Error) { // time stamp it date := time.LocalTime().Format(time.RFC1123) req.Header["Date"] = date // sign the request bucket.Sign(req) // open a connection conn, err := net.Dial("tcp", "", req.URL.Host+":"+req.URL.Scheme) if err != nil { return nil, err } // send the request req.Write(conn) // now read the response reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, req.Method) if err != nil { return nil, err } return }
func (h *HttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { r.Write(os.Stdout) for _, route := range routes { if route.pattern.MatchString(r.RawURL) { route.handler(h.Repo, w, r) break } } }
func SendTo(req *http.Request, conn net.Conn) (e os.Error) { // Write our request struct to the connection in http wire format. e = req.Write(conn) if e != nil { fmt.Println("Error writing request:", e) } fmt.Printf("Wrote request\n") return }
func (proxy *Proxy) ServeHTTP(conn *http.Conn, req *http.Request) { // Open a connection to the Hub. hubconn, err := net.Dial("tcp", "", remoteAddr) if err != nil { if debugMode { fmt.Printf("Couldn't connect to remote %s: %v\n", remoteHost, err) } return } hub := tls.Client(hubconn, tlsconf.Config) defer hub.Close() // Modify the request Host: header. req.Host = remoteHost // Send the request to the Hub. err = req.Write(hub) if err != nil { if debugMode { fmt.Printf("Error writing to the hub: %v\n", err) } return } // Parse the response from the Hub. resp, err := http.ReadResponse(bufio.NewReader(hub), req.Method) if err != nil { if debugMode { fmt.Printf("Error parsing response from the hub: %v\n", err) } return } // Set the received headers back to the initial connection. for k, v := range resp.Header { conn.SetHeader(k, v) } // Read the full response body. body, err := ioutil.ReadAll(resp.Body) if err != nil { if debugMode { fmt.Printf("Error reading response from the hub: %v\n", err) } resp.Body.Close() return } // Write the response body back to the initial connection. resp.Body.Close() conn.WriteHeader(resp.StatusCode) conn.Write(body) }
func send(req *http.Request) (resp *http.Response, err os.Error) { if req.URL.Scheme != "http" && req.URL.Scheme != "https" { return nil, nil } addr := req.URL.Host if !hasPort(addr) { addr += ":" + req.URL.Scheme } /*info := req.URL.Userinfo if len(info) > 0 { enc := base64.URLEncoding encoded := make([]byte, enc.EncodedLen(len(info))) enc.Encode(encoded, []byte(info)) if req.Header == nil { req.Header = make(map[string]string) } req.Header["Authorization"] = "Basic " + string(encoded) } */ var conn io.ReadWriteCloser if req.URL.Scheme == "http" { conn, err = net.Dial("tcp", addr) } else { // https conn, err = tls.Dial("tcp", addr, nil) } if err != nil { return nil, err } err = req.Write(conn) if err != nil { conn.Close() return nil, err } reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, req) if err != nil { conn.Close() return nil, err } resp.Body = readClose{resp.Body, conn} return }
func send(req *http.Request) (resp *http.Response, err os.Error) { //dump, _ := http.DumpRequest(req, true) //fmt.Fprintf(os.Stderr, "%s", dump) //fmt.Fprintf(os.Stderr, "\n--- body:\n%s\n---", bodyString(req.Body)) if req.URL.Scheme != "http" && req.URL.Scheme != "https" { return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme} } addr := req.URL.Host var conn net.Conn switch req.URL.Scheme { case "http": if !hasPort(addr) { addr += ":http" } conn, err = net.Dial("tcp", addr) case "https": if !hasPort(addr) { addr += ":https" } conn, err = tls.Dial("tcp", addr, nil) } if err != nil { return nil, err } err = req.Write(conn) if err != nil { conn.Close() return nil, err } reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, req) if err != nil { conn.Close() return nil, err } resp.Body = readClose{resp.Body, conn} return }
func sendPost(postRequest *http.Request) (body string, err os.Error) { // Create and use TCP connection (lifted mostly wholesale from http.send) conn, err := net.Dial("tcp", "api.flickr.com:80") defer conn.Close() if err != nil { return "", err } postRequest.Write(conn) reader := bufio.NewReader(conn) resp, err := http.ReadResponse(reader, postRequest.Method) if err != nil { return "", err } rawBody, _ := ioutil.ReadAll(resp.Body) return string(rawBody), nil }
func main() { url := "http://twitter.com/statuses/public_timeline.json" var req http.Request req.URL, _ = http.ParseURL(url) addr := req.URL.Host addr += ":http" conn, _ := net.Dial("tcp", "", addr) _ = req.Write(conn) reader := bufio.NewReader(conn) resp, _ := http.ReadResponse(reader) r := io.Reader(reader) if v := resp.GetHeader("Content-Length"); v != "" { n, _ := strconv.Atoi64(v) r = io.LimitReader(r, n) } resp.Body = readClose{r, conn} b, _ := io.ReadAll(resp.Body) resp.Body.Close() fmt.Println(string(b)) }
func send(req *http.Request) (resp *http.Response, err os.Error) { if req.URL.Scheme != "http" { return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme} } addr := req.URL.Host if !hasPort(addr) { addr += ":http" } info := req.URL.Userinfo if len(info) > 0 { enc := base64.URLEncoding encoded := make([]byte, enc.EncodedLen(len(info))) enc.Encode(encoded, strings.Bytes(info)) if req.Header == nil { req.Header = make(map[string]string) } req.Header["Authorization"] = "Basic " + string(encoded) } conn, err := net.Dial("tcp", "", addr) if err != nil { return nil, err } err = req.Write(conn) if err != nil { conn.Close() return nil, err } reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, req.Method) if err != nil { conn.Close() return nil, err } resp.Body = readClose{resp.Body, conn} return }
// execute a request; date it, sign it, send it // note: specialcase is temporary hack to set Content-Length: 0 when needed func (p *Propolis) SignAndExecute(req *http.Request, specialcase bool) (resp *http.Response, err os.Error) { // time stamp it date := time.LocalTime().Format(time.RFC1123) req.Header.Set("Date", date) // sign the request p.SignRequest(req) // open a connection conn, err := net.Dial("tcp", req.URL.Host+":"+req.URL.Scheme) if err != nil { return nil, err } // send the request if specialcase { var buf bytes.Buffer req.Write(&buf) fixed := bytes.Replace(buf.Bytes(), []byte("User-Agent: Go http package\r\n"), []byte("User-Agent: Go http package\r\nContent-Length: 0\r\n"), 1) _, err = conn.Write(fixed) } else { err = req.Write(conn) } if err != nil { return } // now read the response reader := bufio.NewReader(conn) resp, err = http.ReadResponse(reader, req) if err != nil { return nil, err } return }
func (frontend *Frontend) ServeHTTP(conn *http.Conn, req *http.Request) { if frontend.enforceHost && req.Host != frontend.officialHost { conn.SetHeader("Location", frontend.officialRedirectURL) conn.WriteHeader(http.StatusMovedPermanently) conn.Write(frontend.officialRedirectHTML) logRequest(http.StatusMovedPermanently, req.Host, conn) return } originalHost := req.Host // Open a connection to the App Engine server. gaeConn, err := net.Dial("tcp", "", frontend.gaeAddr) if err != nil { if debugMode { fmt.Printf("Couldn't connect to remote %s: %v\n", frontend.gaeHost, err) } serveError502(conn, originalHost) return } var gae net.Conn if frontend.gaeTLS { gae = tls.Client(gaeConn, tlsconf.Config) defer gae.Close() } else { gae = gaeConn } // Modify the request Host: header. req.Host = frontend.gaeHost // Send the request to the App Engine server. err = req.Write(gae) if err != nil { if debugMode { fmt.Printf("Error writing to App Engine: %v\n", err) } serveError502(conn, originalHost) return } // Parse the response from App Engine. resp, err := http.ReadResponse(bufio.NewReader(gae), req.Method) if err != nil { if debugMode { fmt.Printf("Error parsing response from App Engine: %v\n", err) } serveError502(conn, originalHost) return } // Read the full response body. body, err := ioutil.ReadAll(resp.Body) if err != nil { if debugMode { fmt.Printf("Error reading response from App Engine: %v\n", err) } serveError502(conn, originalHost) resp.Body.Close() return } // Set the received headers back to the initial connection. for k, v := range resp.Header { conn.SetHeader(k, v) } // Write the response body back to the initial connection. resp.Body.Close() conn.WriteHeader(resp.StatusCode) conn.Write(body) logRequest(resp.StatusCode, originalHost, conn) }
func (frontend *Frontend) ServeHTTP(conn http.ResponseWriter, req *http.Request) { originalHost := req.Host // Redirect all requests to the "official" public host if the Host header // doesn't match. if !frontend.isValidHost(originalHost) { conn.Header().Set("Location", frontend.RedirectURL) conn.WriteHeader(http.StatusMovedPermanently) conn.Write(frontend.RedirectHTML) frontend.Log(HTTPS_REDIRECT, http.StatusMovedPermanently, originalHost, req) return } // Return the HTTP 503 error page if we're in maintenance mode. if frontend.MaintenanceMode { headers := conn.Header() headers.Set("Content-Type", "text/html; charset=utf-8") headers.Set("Content-Length", frontend.Error503Length) conn.WriteHeader(http.StatusServiceUnavailable) conn.Write(frontend.Error503) frontend.Log(HTTPS_MAINTENANCE, http.StatusServiceUnavailable, originalHost, req) return } reqPath := req.URL.Path // Handle requests for any files exposed within the static directory. if staticFile, ok := frontend.StaticFiles[reqPath]; ok { expires := time.SecondsToUTC(time.Seconds() + frontend.StaticMaxAge) headers := conn.Header() headers.Set("Expires", expires.Format(http.TimeFormat)) headers.Set("Cache-Control", frontend.StaticCache) headers.Set("Etag", staticFile.ETag) if req.Header.Get("If-None-Match") == staticFile.ETag { conn.WriteHeader(http.StatusNotModified) frontend.Log(HTTPS_STATIC, http.StatusNotModified, originalHost, req) return } // Special case /.well-known/oauth.json?callback= requests. if reqPath == "/.well-known/oauth.json" && req.URL.RawQuery != "" { query, err := http.ParseQuery(req.URL.RawQuery) if err != nil { logging.Error("Error parsing oauth.json query string %q: %s", req.URL.RawQuery, err) frontend.ServeError400(conn, originalHost, req) return } if callbackList, found := query["callback"]; found { callback := callbackList[0] if callback != "" { respLen := len(callback) + len(staticFile.Content) + 2 headers.Set("Content-Type", "text/javascript") headers.Set("Content-Length", fmt.Sprintf("%d", respLen)) conn.WriteHeader(http.StatusOK) conn.Write([]byte(callback)) conn.Write([]byte{'('}) conn.Write(staticFile.Content) conn.Write([]byte{')'}) frontend.Log(HTTPS_STATIC, http.StatusOK, originalHost, req) return } } } headers.Set("Content-Type", staticFile.Mimetype) headers.Set("Content-Length", staticFile.Size) conn.WriteHeader(http.StatusOK) conn.Write(staticFile.Content) frontend.Log(HTTPS_STATIC, http.StatusOK, originalHost, req) return } if frontend.LiveMode { // Handle WebSocket requests. if strings.HasPrefix(reqPath, frontend.WebsocketPrefix) { websocket.Handler(frontend.getWebSocketHandler()).ServeHTTP(conn, req) return } // Handle long-polling Comet requests. if strings.HasPrefix(reqPath, frontend.CometPrefix) { query, err := http.ParseQuery(req.URL.RawQuery) if err != nil { logging.Error("Error parsing Comet query string %q: %s", req.URL.RawQuery, err) frontend.ServeError400(conn, originalHost, req) return } queryReq, found := query["q"] if !found { frontend.ServeError400(conn, originalHost, req) return } response, status := getLiveItems(queryReq[0]) headers := conn.Header() headers.Set("Content-Type", "application/json") headers.Set("Content-Length", fmt.Sprintf("%d", len(response))) conn.WriteHeader(status) conn.Write(response) frontend.Log(HTTPS_COMET, status, originalHost, req) return } } // Open a connection to the upstream server. upstreamConn, err := net.Dial("tcp", frontend.upstreamAddr) if err != nil { logging.Error("Couldn't connect to upstream: %s", err) frontend.ServeError502(conn, originalHost, req) return } var clientIP string var upstream net.Conn splitPoint := strings.LastIndex(req.RemoteAddr, ":") if splitPoint == -1 { clientIP = req.RemoteAddr } else { clientIP = req.RemoteAddr[0:splitPoint] } if frontend.upstreamTLS { upstream = tls.Client(upstreamConn, tlsconf.Config) defer upstream.Close() } else { upstream = upstreamConn } // Modify the request Host: and User-Agent: headers. req.Host = frontend.upstreamHost req.Header.Set( "User-Agent", fmt.Sprintf("%s, %s, %s", req.UserAgent(), clientIP, originalHost)) // Send the request to the upstream server. err = req.Write(upstream) if err != nil { logging.Error("Error writing to the upstream server: %s", err) frontend.ServeError502(conn, originalHost, req) return } // Parse the response from upstream. resp, err := http.ReadResponse(bufio.NewReader(upstream), req) if err != nil { logging.Error("Error parsing response from upstream: %s", err) frontend.ServeError502(conn, originalHost, req) return } defer resp.Body.Close() // Get the original request header. headers := conn.Header() // Set a variable to hold the X-Live header value if present. var liveLength int if frontend.LiveMode { xLive := resp.Header.Get("X-Live") if xLive != "" { // If the X-Live header was set, parse it into an int. liveLength, err = strconv.Atoi(xLive) if err != nil { logging.Error("Error converting X-Live header value %q: %s", xLive, err) frontend.ServeError500(conn, originalHost, req) return } resp.Header.Del("X-Live") } } var body []byte if liveLength > 0 { var gzipSet bool var respBody io.ReadCloser // Check Content-Encoding to see if upstream sent gzipped content. if resp.Header.Get("Content-Encoding") == "gzip" { gzipSet = true respBody, err = gzip.NewReader(resp.Body) if err != nil { logging.Error("Error reading gzipped response from upstream: %s", err) frontend.ServeError500(conn, originalHost, req) return } defer respBody.Close() } else { respBody = resp.Body } // Read the X-Live content from the response body. liveMessage := make([]byte, liveLength) n, err := respBody.Read(liveMessage) if n != liveLength || err != nil { logging.Error("Error reading X-Live response from upstream: %s", err) frontend.ServeError500(conn, originalHost, req) return } // Read the response to send back to the original request. body, err = ioutil.ReadAll(respBody) if err != nil { logging.Error("Error reading non X-Live response from upstream: %s", err) frontend.ServeError500(conn, originalHost, req) return } // Re-encode the response if it had been gzipped by upstream. if gzipSet { buffer := &bytes.Buffer{} encoder, err := gzip.NewWriter(buffer) if err != nil { logging.Error("Error creating a new gzip Writer: %s", err) frontend.ServeError500(conn, originalHost, req) return } n, err = encoder.Write(body) if n != len(body) || err != nil { logging.Error("Error writing to the gzip Writer: %s", err) frontend.ServeError500(conn, originalHost, req) return } err = encoder.Close() if err != nil { logging.Error("Error finalising the write to the gzip Writer: %s", err) frontend.ServeError500(conn, originalHost, req) return } body = buffer.Bytes() } resp.Header.Set("Content-Length", fmt.Sprintf("%d", len(body))) liveChannel <- liveMessage } else { // Read the full response body. body, err = ioutil.ReadAll(resp.Body) if err != nil { logging.Error("Error reading response from upstream: %s", err) frontend.ServeError502(conn, originalHost, req) return } } // Set the received headers back to the initial connection. for k, values := range resp.Header { for _, v := range values { headers.Add(k, v) } } // Write the response body back to the initial connection. conn.WriteHeader(resp.StatusCode) conn.Write(body) frontend.Log(HTTPS_UPSTREAM, resp.StatusCode, originalHost, req) }
func (s Session) perform(method, url, data string) { var req http.Request req.URL, _ = http.ParseURL(url) req.Method = method req.Header = s.headers req.ContentLength = int64(len(data)) req.Body = myCloser{bytes.NewBufferString(data)} if *verbose { req.Write(os.Stderr) } retry := 0 request: req.Body = myCloser{bytes.NewBufferString(data)} // recreate anew, in case of retry err := s.conn.Write(&req) if err != nil { if retry < 2 { if err == io.ErrUnexpectedEOF { // the underlying connection has been closed "gracefully" retry++ s.conn.Close() s.conn = dial(s.host) goto request } else if protoerr, ok := err.(*http.ProtocolError); ok && protoerr == http.ErrPersistEOF { // the connection has been closed in an HTTP keepalive sense retry++ s.conn.Close() s.conn = dial(s.host) goto request } } fmt.Fprintln(os.Stderr, "http-gonsole: could not send request:", err) os.Exit(1) } r, err := s.conn.Read(&req) if err != nil { if protoerr, ok := err.(*http.ProtocolError); ok && protoerr == http.ErrPersistEOF { // the remote requested that this be the last request serviced, // we proceed as the response is still valid defer s.conn.Close() defer func() { s.conn = dial(s.host) }() goto output } fmt.Fprintln(os.Stderr, "http-gonsole: could not read response:", err) os.Exit(1) } output: if len(data) > 0 { fmt.Println() } if r.StatusCode >= 500 { fmt.Printf(colorize(C_5xx, "%s %s\n"), r.Proto, r.Status) } else if r.StatusCode >= 400 { fmt.Printf(colorize(C_4xx, "%s %s\n"), r.Proto, r.Status) } else if r.StatusCode >= 300 { fmt.Printf(colorize(C_3xx, "%s %s\n"), r.Proto, r.Status) } else if r.StatusCode >= 200 { fmt.Printf(colorize(C_2xx, "%s %s\n"), r.Proto, r.Status) } if len(r.Header) > 0 { for key, arr := range r.Header { for _, val := range arr { fmt.Printf(colorize(C_Header, "%s: "), key) fmt.Println(val) } } fmt.Println() } if *rememberCookies { if cookies, found := r.Header["Set-Cookie"]; found { for _, h := range cookies { cookie := new(Cookie) cookie.Items = map[string]string{} re, _ := regexp.Compile("^[^=]+=[^;]+(; *(expires=[^;]+|path=[^;,]+|domain=[^;,]+|secure))*,?") rs := re.FindAllString(h, -1) for _, ss := range rs { m := strings.Split(ss, ";", -1) for _, n := range m { t := strings.Split(n, "=", 2) if len(t) == 2 { t[0] = strings.Trim(t[0], " ") t[1] = strings.Trim(t[1], " ") switch t[0] { case "domain": cookie.domain = t[1] case "path": cookie.path = t[1] case "expires": tm, err := time.Parse("Fri, 02-Jan-2006 15:04:05 MST", t[1]) if err != nil { tm, err = time.Parse("Fri, 02-Jan-2006 15:04:05 -0700", t[1]) } cookie.expires = tm case "secure": cookie.secure = true case "HttpOnly": cookie.httpOnly = true default: cookie.Items[t[0]] = t[1] } } } } *s.cookies = append(*s.cookies, cookie) } } } h := r.Header.Get("Content-Length") if len(h) > 0 { n, _ := strconv.Atoi64(h) b := make([]byte, n) io.ReadFull(r.Body, b) fmt.Println(string(b)) } else if method != "HEAD" { b, _ := ioutil.ReadAll(r.Body) fmt.Println(string(b)) } else { // TODO: streaming? } }