Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Parse URLs (actually URIs, but that seems overly pedantic). | 5 // Parse URLs (actually URIs, but that seems overly pedantic). |
6 // RFC 3986 | 6 // RFC 3986 |
7 | 7 |
8 package http | 8 package http |
9 | 9 |
10 import ( | 10 import ( |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 url = new(URL) | 393 url = new(URL) |
394 url.Raw = rawurl | 394 url.Raw = rawurl |
395 | 395 |
396 // Split off possible leading "http:", "mailto:", etc. | 396 // Split off possible leading "http:", "mailto:", etc. |
397 // Cannot contain escaped characters. | 397 // Cannot contain escaped characters. |
398 var path string | 398 var path string |
399 if url.Scheme, path, err = getscheme(rawurl); err != nil { | 399 if url.Scheme, path, err = getscheme(rawurl); err != nil { |
400 goto Error | 400 goto Error |
401 } | 401 } |
402 | 402 |
403 » if url.Scheme != "" && (len(path) == 0 || path[0] != '/') { | 403 » if url.Scheme != "" && !strings.HasPrefix(path, "/") { |
404 // RFC 2396: | 404 // RFC 2396: |
405 // Absolute URI (has scheme) with non-rooted path | 405 // Absolute URI (has scheme) with non-rooted path |
406 // is uninterpreted. It doesn't even have a ?query. | 406 // is uninterpreted. It doesn't even have a ?query. |
407 // This is the case that handles mailto:name@example.com. | 407 // This is the case that handles mailto:name@example.com. |
408 url.RawPath = path | 408 url.RawPath = path |
409 | 409 |
410 if url.Path, err = urlUnescape(path, encodeOpaque); err != nil { | 410 if url.Path, err = urlUnescape(path, encodeOpaque); err != nil { |
411 goto Error | 411 goto Error |
412 } | 412 } |
413 url.OpaquePath = true | 413 url.OpaquePath = true |
414 } else { | 414 } else { |
415 // Split off query before parsing path further. | 415 // Split off query before parsing path further. |
416 url.RawPath = path | 416 url.RawPath = path |
417 path, query := split(path, '?', false) | 417 path, query := split(path, '?', false) |
418 if len(query) > 1 { | 418 if len(query) > 1 { |
419 url.RawQuery = query[1:] | 419 url.RawQuery = query[1:] |
420 } | 420 } |
421 | 421 |
422 // Maybe path is //authority/path | 422 // Maybe path is //authority/path |
423 » » if url.Scheme != "" && len(path) > 2 && path[0:2] == "//" { | 423 » » if strings.HasPrefix(path, "//") && !strings.HasPrefix(path, "// /") { |
424 url.RawAuthority, path = split(path[2:], '/', false) | 424 url.RawAuthority, path = split(path[2:], '/', false) |
425 url.RawPath = url.RawPath[2+len(url.RawAuthority):] | 425 url.RawPath = url.RawPath[2+len(url.RawAuthority):] |
426 } | 426 } |
427 | 427 |
428 // Split authority into userinfo@host. | 428 // Split authority into userinfo@host. |
429 // If there's no @, split's default is wrong. Check explicitly. | 429 // If there's no @, split's default is wrong. Check explicitly. |
430 var rawHost string | 430 var rawHost string |
431 if strings.Index(url.RawAuthority, "@") < 0 { | 431 if strings.Index(url.RawAuthority, "@") < 0 { |
432 rawHost = url.RawAuthority | 432 rawHost = url.RawAuthority |
433 } else { | 433 } else { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
520 func EncodeQuery(m map[string][]string) string { | 520 func EncodeQuery(m map[string][]string) string { |
521 parts := make([]string, 0, len(m)) // will be large enough for most uses | 521 parts := make([]string, 0, len(m)) // will be large enough for most uses |
522 for k, vs := range m { | 522 for k, vs := range m { |
523 prefix := URLEscape(k) + "=" | 523 prefix := URLEscape(k) + "=" |
524 for _, v := range vs { | 524 for _, v := range vs { |
525 parts = append(parts, prefix+URLEscape(v)) | 525 parts = append(parts, prefix+URLEscape(v)) |
526 } | 526 } |
527 } | 527 } |
528 return strings.Join(parts, "&") | 528 return strings.Join(parts, "&") |
529 } | 529 } |
530 | |
531 // cleanURLForRequest cleans URLs as parsed from ReadRequest. | |
rsc
2011/01/11 16:08:22
I agree with adg that this code should be in ReadR
| |
532 // ReadRequest uses ParseURL which accepts a superset of URL formats | |
533 // which are valid for web requests (scheme-relative URLs, for example) | |
534 // Ideally ReadRequest should use a different parse function for HTTP | |
535 // serving context, but for now we'll just fix it up here. | |
536 func cleanURLForHTTPRequest(url *URL) { | |
adg
2011/01/11 02:44:56
I'm a little uncomfortable with the naming and loc
| |
537 if url.Scheme == "" && url.RawAuthority != "" { | |
538 prefix := "//" + url.RawAuthority | |
539 url.Host = "" | |
540 url.RawAuthority = "" | |
541 url.RawUserinfo = "" | |
542 url.Path = prefix + url.Path | |
543 url.RawPath = prefix + url.RawPath | |
544 } | |
545 } | |
OLD | NEW |