// SortURLParams return url with sorted get parameters func SortURLParams(u *url.URL) string { query := u.Query() if len(query) == 0 { return u.RequestURI() } result := u.Path + "?" var sortedQuery []string for qp := range query { sortedQuery = append(sortedQuery, qp) } sort.Strings(sortedQuery) for _, qp := range sortedQuery { value := strings.Join(query[qp], "") if value == "" { result += qp + "&" } else { result += qp + "=" + value + "&" } } result = result[0 : len(result)-1] if u.Fragment != "" { result += "#" + u.Fragment } return result }
func writeRequests(conn net.Conn, ch <-chan int, requestsChan chan<- int, testUri *url.URL) { var requestsWritten int w := bufio.NewWriter(conn) requestUri := testUri.RequestURI() delimiter := "?" if strings.Contains(requestUri, "?") { delimiter = "&" } for _ = range ch { requestStr := []byte(fmt.Sprintf("GET %s%s%d HTTP/1.1\r\nHost: %s\r\nUser-Agent: go-cdn-booster-bench\r\n\r\n", requestUri, delimiter, rand.Intn(*filesCount), testUri.Host)) if _, err := w.Write(requestStr); err != nil { log.Fatalf("Error=[%s] when writing HTTP request [%d] to connection\n", err, requestsWritten) } requestsWritten += 1 select { case requestsChan <- requestsWritten: default: if err := w.Flush(); err != nil { log.Fatalf("Error when flushing requests' buffer: [%s]\n", err) } requestsChan <- requestsWritten } if requestsWritten == *requestsPerConnectionCount { break } } if err := w.Flush(); err != nil { log.Fatalf("Error when flushing requests' buffer: [%s]\n", err) } }
// sendUnix sends a request or response via a Unix socket. func sendUnix(addr *url.URL, payload interface{}) error { conn, err := net.Dial("unix", addr.RequestURI()) if err != nil { log.WithFields(log.Fields{ "error": err, "addr": addr, "payload": payload, }).Error("failed to connect to unix socket") return err } defer logx.LogReturnedErr(conn.Close, log.Fields{"addr": addr}, "failed to close unix connection", ) if err := SendConnData(conn, payload); err != nil { return err } resp := &Response{} if err := UnmarshalConnData(conn, resp); err != nil { return err } return resp.Error }
func debugUrl(u *url.URL) { logger.Println("Host:", u.Host) logger.Println("Path:", u.Path) logger.Println("Request URI:", u.RequestURI()) logger.Println("Scheme:", u.Scheme) logger.Println("Query:", u.RawQuery) logger.Println("Fragment:", u.Fragment) logger.Println("IsAbs:", u.IsAbs()) }
func parse(s string, base url.URL) (ln []string, as []string) { z := html.NewTokenizer(strings.NewReader(s)) lnm := make(map[string]struct{}) asm := make(map[string]struct{}) // anonymous func used to get attribute values attr := func(a string) string { var av string for { if k, v, ha := z.TagAttr(); string(k) == a { av = string(v) break } else if ha == false { break } } return av } // convert map to slice slc := func(m map[string]struct{}) []string { var v []string for k := range m { v = append(v, k) } sort.Strings(v) return v } for { tt := z.Next() switch tt { case html.ErrorToken: return slc(lnm), slc(asm) case html.StartTagToken, html.EndTagToken: if tn, ha := z.TagName(); ha { tg := string(tn) if av := attr(attrs[tg]); av != "" { switch tg { case atag: if url, err := base.Parse(av); err == nil { if url.Host == base.Host && url.RequestURI() != base.RequestURI() { lnm[url.RequestURI()] = struct{}{} } } case stag, itag, ltag: asm[av] = struct{}{} } } } } } }
// NewClientCodec returns a new rpc.ClientCodec using Yar-RPC on conn. func NewClientHtppCodec(conn io.ReadWriteCloser, u *url.URL, packagerName string) rpc.ClientCodec { packer, _ := getPackager(packagerName) return &clientHttpCodec{ r: bufio.NewReader(conn), w: conn, c: conn, host: u.Host, path: u.RequestURI(), pending: make(map[uint64]string), packer: packer, } }
func (s *V4Signer) canonicalURI(u *url.URL) string { canonicalPath := u.RequestURI() if u.RawQuery != "" { canonicalPath = canonicalPath[:len(canonicalPath)-len(u.RawQuery)-1] } slash := strings.HasSuffix(canonicalPath, "/") canonicalPath = path.Clean(canonicalPath) if canonicalPath != "/" && slash { canonicalPath += "/" } return canonicalPath }
// NewRequest constructs a minimal Request instance given a method and // a target URL. func NewRequest(method string, u *url.URL) *Request { return &Request{ Method: method, URI: u.RequestURI(), Major: 1, Minor: 1, Fields: Fields{ {"Host", u.Host}, }, Scheme: u.Scheme, Remote: u.Host, } }
func normalizePath(p string) string { if strings.Contains(p, "./") || strings.Contains(p, "..") { p, _ = filepath.Abs(p) } if strings.Contains(p, "//") { p = strings.Replace(p, "//", "/", -1) } u := url.URL{Path: p} return u.RequestURI() }
func crawl(url url.URL, ch chan<- SiteMap) { var sm SiteMap // make sure this link hasn't been crawled lc.mux.Lock() _, ok := lc.links[url.RequestURI()] if !ok { lc.links[url.RequestURI()] = struct{}{} lc.mux.Unlock() log.Printf("Crawling URL: %s\n", url.String()) b, err := fetch(url) if err != nil { log.Printf("Error fetching page for URL: %s, err: %s\n", url.String(), err) ch <- SiteMap{} } ln, as := parse(b, url) // create new sitemap and add indexed page sm = SiteMap{URL: url.String()} pg := Page{Path: url.Path, Links: ln, Assets: as} sm.Pages = append(sm.Pages, pg) c := make(chan SiteMap) chLnks := 0 for _, v := range ln { chURL, err := url.Parse(v) if err != nil { log.Printf("Unable parse url for child link %s, error: %s", v, err) continue } go crawl(*chURL, c) chLnks++ } // results of child link crawls for i := 0; i < chLnks; i++ { chsm := <-c if len(chsm.Pages) > 0 { sm.Pages = append(sm.Pages, chsm.Pages...) } } } else { lc.mux.Unlock() } // send a SiteMap, even if empty ch <- sm }
// buildCommonLogLine builds a log entry for req in Apache Common Log Format. // ts is the timestamp with which the entry should be logged. // status and size are used to provide the response HTTP status and size. // Copied from gorilla/handlers/handlers.go, converted to strings instead of byte[] func logHTTP(req *http.Request, url url.URL, ts time.Time, status int, size int) { host, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { host = req.RemoteAddr } uri := req.RequestURI // Requests using the CONNECT method over HTTP/2.0 must use // the authority field (aka r.Host) to identify the target. // Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT if req.ProtoMajor == 2 && req.Method == "CONNECT" { uri = req.Host } if uri == "" { uri = url.RequestURI() } log.WithFields(log.Fields{ "host": host, "method": req.Method, "uri": uri, "proto": req.Proto, "status": status, "size": size, }).Info(status) }
// Log entry for req similar to Apache Common Log Format. // ts is the timestamp with which the entry should be logged. // status, size are used to provide the response HTTP status and size. func buildLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte { username := "******" if url.User != nil { if name := url.User.Username(); name != "" { username = name } } host, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { host = req.RemoteAddr } duration := float64(time.Now().Sub(ts)) / float64(time.Second) logLine := fmt.Sprintf("%s - %s [%s] %s %q %s %d %d %q %0.3f\n", host, username, ts.Format("02/Jan/2006:15:04:05 -0700"), req.Method, url.RequestURI(), req.Proto, status, size, req.UserAgent(), duration, ) return []byte(logLine) }
// buildCommonLogLine builds a log entry for req in Apache Common Log Format. // ts is the timestamp with which the entry should be logged. // status and size are used to provide the response HTTP status and size. func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) []byte { username := "******" if url.User != nil { if name := url.User.Username(); name != "" { username = name } } host, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { host = req.RemoteAddr } uri := url.RequestURI() buf := make([]byte, 0, 3*(len(host)+len(username)+len(req.Method)+len(uri)+len(req.Proto)+50)/2) buf = append(buf, host...) buf = append(buf, " - "...) buf = append(buf, username...) buf = append(buf, " ["...) buf = append(buf, ts.Format("02/Jan/2006:15:04:05 -0700")...) buf = append(buf, `] "`...) buf = append(buf, req.Method...) buf = append(buf, " "...) buf = appendQuoted(buf, uri) buf = append(buf, " "...) buf = append(buf, req.Proto...) buf = append(buf, `" `...) buf = append(buf, strconv.Itoa(status)...) buf = append(buf, " "...) buf = append(buf, strconv.Itoa(size)...) return buf }
func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header) (c *Conn, response *http.Response, err error) { key, err := calcKey() if err != nil { return nil, nil, err } acceptKey := calcAcceptKey(key) c = NewConn(netConn, false) buf := bytes.NewBufferString("GET ") buf.WriteString(u.RequestURI()) buf.WriteString(" HTTP/1.1\r\nHost: ") buf.WriteString(u.Host) buf.WriteString("\r\nUpgrade: websocket\r\nConnection: upgrade\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: ") buf.WriteString(key) buf.WriteString("\r\n") for k, vs := range requestHeader { for _, v := range vs { buf.WriteString(k) buf.WriteString(": ") buf.WriteString(v) buf.WriteString("\r\n") } } buf.WriteString("\r\n") p := buf.Bytes() if _, err := netConn.Write(p); err != nil { return nil, nil, err } resp, err := http.ReadResponse(c.br, &http.Request{Method: "GET", URL: u}) if err != nil { return nil, nil, err } if resp.StatusCode != 101 || !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || resp.Header.Get("Sec-Websocket-Accept") != acceptKey { return nil, resp, ErrBadHandshake } return c, resp, nil }
// NewClient creates a new client connection using the given net connection. // The URL u specifies the host and request URI. Use requestHeader to specify // the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies // (Cookie). Use the response.Header to get the selected subprotocol // (Sec-WebSocket-Protocol) and cookies (Set-Cookie). // // If the WebSocket handshake fails, ErrBadHandshake is returned along with a // non-nil *http.Response so that callers can handle redirects, authentication, // etc. func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { challengeKey, err := generateChallengeKey() if err != nil { return nil, nil, err } acceptKey := computeAcceptKey(challengeKey) c = newConn(netConn, false, readBufSize, writeBufSize) p := c.writeBuf[:0] p = append(p, "GET "...) p = append(p, u.RequestURI()...) p = append(p, " HTTP/1.1\r\nHost: "...) p = append(p, u.Host...) // "Upgrade" is capitalized for servers that do not use case insensitive // comparisons on header tokens. p = append(p, "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: "...) p = append(p, challengeKey...) p = append(p, "\r\n"...) for k, vs := range requestHeader { for _, v := range vs { p = append(p, k...) p = append(p, ": "...) p = append(p, v...) p = append(p, "\r\n"...) } } p = append(p, "\r\n"...) if _, err := netConn.Write(p); err != nil { return nil, nil, err } resp, err := http.ReadResponse(c.br, &http.Request{Method: "GET", URL: u}) if err != nil { return nil, nil, err } if resp.StatusCode != 101 || !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || resp.Header.Get("Sec-Websocket-Accept") != acceptKey { return nil, resp, ErrBadHandshake } c.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") return c, resp, nil }
func TestMakeUserBadHeaderNotBase64Encoded(t *testing.T) { re, UserMap := defaultRE(), NewUserMap() u := url.URL{Scheme: "http", Host: "localhost:8080", Path: "users"} w := httptest.NewRecorder() req, _ := http.NewRequest(strings.ToUpper("POST"), u.RequestURI(), nil) req.Header.Add("Authorization", "Basic brian:password") re.makeUser(UserMap)(w, req) code, gotMsg, err := parseResponse(w) if err != nil { t.Errorf("Problem reading body: %v", err) } if code != http.StatusBadRequest { t.Errorf("unexpected status code: got %v, expected %v", code, http.StatusBadRequest) } expectedMsg := "You must provide properly-formatted credentials. We could not decode your base64-encoded username/password combination." if gotMsg != expectedMsg { t.Errorf("unexpected error message: got %v, expected %v", gotMsg, expectedMsg) } }
//ParseAPIRequestURL takes a net/url URL and returns a models.APIRquest object func ParseAPIRequestURL(url url.URL) APIRequest { r := APIRequest{url, "", ""} splited := strings.Split(url.RequestURI(), "/") r.Method = splited[2] // strip out the beginning of the url and return just the data toReplace := fmt.Sprintf("/api/%s/", r.Method) r.Query = strings.Replace(url.Path, toReplace, "", 1) return r }
func RequireAccount(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { acc := AccountForRequest(w, r) if acc == nil { v := url.Values{} v.Set("next", r.URL.RequestURI()) signinUrl := url.URL{ Path: "/signin", RawQuery: v.Encode(), } http.Redirect(w, r, signinUrl.RequestURI(), http.StatusTemporaryRedirect) return } context.Set(r, ContextKeyAccount, acc) h.ServeHTTP(w, r) }) }
// NewClient creates a new client connection using the given net connection. // The URL u specifies the host and request URI. The header specifies optional // Origin, Sec-WebSocket-Protocol and Cookie headers. func NewClient(netConn net.Conn, u *url.URL, header http.Header, readBufSize, writeBufSize int) (c *Conn, subprotocol string, err error) { challengeKey, err := generateChallengeKey() if err != nil { return nil, "", err } acceptKey := computeAcceptKey(challengeKey) c = newConn(netConn, false, readBufSize, writeBufSize) p := c.writeBuf[:0] p = append(p, "GET "...) p = append(p, u.RequestURI()...) p = append(p, " HTTP/1.1\r\nHost: "...) p = append(p, u.Host...) p = append(p, "\r\nUpgrade: websocket\r\nConnection: upgrade\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: "...) p = append(p, challengeKey...) p = append(p, "\r\n"...) for k, vs := range header { for _, v := range vs { p = append(p, k...) p = append(p, ": "...) p = append(p, v...) p = append(p, "\r\n"...) } } p = append(p, "\r\n"...) if _, err := netConn.Write(p); err != nil { return nil, "", err } resp, err := http.ReadResponse(c.br, &http.Request{Method: "GET"}) if err != nil { return nil, "", err } if resp.StatusCode != 101 || !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || resp.Header.Get("Sec-Websocket-Accept") != acceptKey { return nil, "", errors.New("websocket: bad handshake") } return c, resp.Header.Get("Sec-WebSocket-Protocol"), nil }
func (c *appContext) prepareSubmission(s *Submitter) { //todo: address := url.URL{} address.Host = "localhost:3000" address.Path = "/unlock/" address.Path += s.Id.Hex() fmt.Println("URL build result: ",address.RequestURI()) fmt.Println("Full path: ", address.String()[2:]) result, err := qrencode.Encode(address.String()[2:], qrencode.ECLevelL) if err != nil { //handle error fmt.Println(err) return } fmt.Println(result.String() //todo: return }
func TestMakeUserBadHeaderTooManyFields(t *testing.T) { re, UserMap := defaultRE(), NewUserMap() u := url.URL{Scheme: "http", Host: "localhost:8080", Path: "users"} w := httptest.NewRecorder() req, _ := http.NewRequest(strings.ToUpper("POST"), u.RequestURI(), nil) req.Header.Add("foo", "bar") req.Header.Add("bar", "foo") re.makeUser(UserMap)(w, req) code, gotMsg, err := parseResponse(w) if err != nil { t.Errorf("Problem reading body: %v", err) } if code != http.StatusBadRequest { t.Errorf("unexpected status code: got %v, expected %v", code, http.StatusBadRequest) } expectedMsg := "You must provide properly-formatted credentials. Expecting HTTP Basic Authentication scheme and base64-encoded username:password pair." if gotMsg != expectedMsg { t.Errorf("unexpected error message: got %v, expected %v", gotMsg, expectedMsg) } }
func TestMakeUserBadHeaderNotBasicAuth(t *testing.T) { re, UserMap := defaultRE(), NewUserMap() u := url.URL{Scheme: "http", Host: "localhost:8080", Path: "users"} w := httptest.NewRecorder() req, _ := http.NewRequest(strings.ToUpper("POST"), u.RequestURI(), nil) var b bytes.Buffer enc := base64.NewEncoder(base64.StdEncoding, &b) enc.Write([]byte("brian:password")) req.Header.Add("Authorization", "NotBasic"+" "+b.String()) re.makeUser(UserMap)(w, req) code, gotMsg, err := parseResponse(w) if err != nil { t.Errorf("Problem reading body: %v", err) } if code != http.StatusBadRequest { t.Errorf("unexpected status code: got %v, expected %v", code, http.StatusBadRequest) } expectedMsg := "You must provide properly-formatted credentials. You either did not use the HTTP Basic Authentication scheme or did not provide a username/password field. We have not yet checked whether it is a valid base64 encoding; we have only checked whether the field was present at all." if gotMsg != expectedMsg { t.Errorf("unexpected error message: got %v, expected %v", gotMsg, expectedMsg) } }
func (s *Store) RefererId(ref string) (siteId int64, uriId int64, e error) { if strings.TrimSpace(ref) == "" { return 0, 0, nil } var u *url.URL u, e = url.Parse(ref) if e != nil { return } siteId, e = s.SiteId(u.Host) if e != nil { return } uriStr := strings.TrimPrefix(u.RequestURI(), "/") uriId, e = s.UriId(uriStr) if e != nil { return } return }
// buildCommonLogLine builds a log entry for req in Apache Common Log Format. // ts is the timestamp with which the entry should be logged. // status and size are used to provide the response HTTP status and size. // // This function was taken from the Gorilla toolkit's handlers.go file. func buildCommonLogLine( req *http.Request, url url.URL, ts time.Time, status int, size int) []byte { username := "******" if url.User != nil { if name := url.User.Username(); name != "" { username = name } } host, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { host = req.RemoteAddr } uri := req.RequestURI // Requests using the CONNECT method over HTTP/2.0 must use // the authority field (aka r.Host) to identify the target. // Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT if req.ProtoMajor == 2 && req.Method == "CONNECT" { uri = req.Host } if uri == "" { uri = url.RequestURI() } buf := make([]byte, 0, 3*(len(host)+len(username)+ len(req.Method)+len(uri)+len(req.Proto)+50)/2) buf = append(buf, host...) buf = append(buf, " - "...) buf = append(buf, username...) buf = append(buf, " ["...) buf = append(buf, ts.Format("02/Jan/2006:15:04:05 -0700")...) buf = append(buf, `] "`...) buf = append(buf, req.Method...) buf = append(buf, " "...) buf = appendQuoted(buf, uri) buf = append(buf, " "...) buf = append(buf, req.Proto...) buf = append(buf, `" `...) buf = append(buf, strconv.Itoa(status)...) buf = append(buf, " "...) buf = append(buf, strconv.Itoa(size)...) return buf }
// streamUnix streams data from a unix socket to a destination writer. func streamUnix(dest io.Writer, addr *url.URL) error { conn, err := net.Dial("unix", addr.RequestURI()) if err != nil { log.WithFields(log.Fields{ "addr": addr, "error": err, }).Error("failed to connect to stream socket") return err } defer logx.LogReturnedErr(conn.Close, log.Fields{"addr": addr}, "failed to close stream connection", ) if _, err := io.Copy(dest, conn); err != nil { log.WithFields(log.Fields{ "addr": addr, "error": err, }).Error("failed to stream data") return err } return nil }
// writeRequestLog writes a log entry to the supplied logrus logger. // ts is the timestamp with which the entry should be logged. // trnasactionID is a unique id for this request. // status and size are used to provide the response HTTP status and size. func writeRequestLog(logger *log.Logger, req *http.Request, transactionID string, url url.URL, responseTime time.Duration, status, size int) { username := "******" if url.User != nil { if name := url.User.Username(); name != "" { username = name } } host, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { host = req.RemoteAddr } uri := req.RequestURI // Requests using the CONNECT method over HTTP/2.0 must use // the authority field (aka r.Host) to identify the target. // Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT if req.ProtoMajor == 2 && req.Method == "CONNECT" { uri = req.Host } if uri == "" { uri = url.RequestURI() } logger.WithFields(log.Fields{ "responsetime": int64(responseTime.Seconds() * 1000), "host": host, "username": username, "method": req.Method, "transaction_id": transactionID, "uri": uri, "protocol": req.Proto, "status": status, "size": size, "referer": req.Referer(), "userAgent": req.UserAgent(), }).Info("") }
// Log entry for req similar to Apache Common Log Format. // ts is the timestamp with which the entry should be logged. // status, size are used to provide the response HTTP status and size. func buildLogLine(username, upstream string, req *http.Request, url url.URL, ts time.Time, status int, size int) []byte { if username == "" { username = "******" } if upstream == "" { upstream = "-" } if url.User != nil && username == "-" { if name := url.User.Username(); name != "" { username = name } } client := req.Header.Get("X-Real-IP") if client == "" { client = req.RemoteAddr } if c, _, err := net.SplitHostPort(client); err == nil { client = c } duration := float64(time.Now().Sub(ts)) / float64(time.Second) logLine := fmt.Sprintf("%s - %s [%s] %s %s %s %q %s %q %d %d %0.3f\n", client, username, ts.Format("02/Jan/2006:15:04:05 -0700"), req.Host, req.Method, upstream, url.RequestURI(), req.Proto, req.UserAgent(), status, size, duration, ) return []byte(logLine) }
// buildCommonLogLine builds a log entry for req in Apache Common Log Format. // ts is the timestamp with which the entry should be logged. // status and size are used to provide the response HTTP status and size. // Copied from gorilla/handlers/handlers.go, converted to strings instead of byte[] func buildCommonLogLine(req *http.Request, url url.URL, ts time.Time, status int, size int) string { username := "******" if url.User != nil { if name := url.User.Username(); name != "" { username = name } } host, _, err := net.SplitHostPort(req.RemoteAddr) if err != nil { host = req.RemoteAddr } uri := req.RequestURI // Requests using the CONNECT method over HTTP/2.0 must use // the authority field (aka r.Host) to identify the target. // Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT if req.ProtoMajor == 2 && req.Method == "CONNECT" { uri = req.Host } if uri == "" { uri = url.RequestURI() } return fmt.Sprintf("%s %s [%s] \"%s %s %s\" %d %d", host, username, ts.Format("02/Jan/2006:15:04:05 -0700"), req.Method, uri, req.Proto, status, size) }
func escapedPath(urlObj *url.URL) string { // the escape method of url.URL should be public // that would avoid this split. parts := strings.SplitN(urlObj.RequestURI(), "?", 2) return parts[0] }
func createRequest(url *url.URL) *http.Request { req, _ := http.NewRequest("GET", url.RequestURI(), nil) req.Header.Set("User-Agent", "resizr "+Version) req.URL = url return req }