Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(183)

Side by Side Diff: src/pkg/http/url.go

Issue 3910042: code review 3910042: http: fix scheme-relative URL parsing; add ParseRequestURL (Closed)
Patch Set: code review 3910042: http: fix handling of scheme-relative URL parsing Created 14 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « src/pkg/http/serve_test.go ('k') | src/pkg/http/url_test.go » ('j') | src/pkg/http/url_test.go » ('J')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b