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

Delta Between Two Patch Sets: src/pkg/net/url/url.go

Issue 8325045: code review 8325045: net/url: Add ParseUserinfo() function
Left Patch Set: diff -r f95d161ca3cb https://code.google.com/p/go Created 10 years, 10 months ago
Right Patch Set: diff -r 61b8f10038ed https://code.google.com/p/go Created 10 years, 8 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/net/url/url_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 // Package url parses URLs and implements query escaping. 5 // Package url parses URLs and implements query escaping.
6 // See RFC 3986. 6 // See RFC 3986.
7 package url 7 package url
8 8
9 import ( 9 import (
10 "bytes" 10 "bytes"
11 "encoding/binary"
12 "errors" 11 "errors"
12 "fmt"
13 "sort" 13 "sort"
14 "strconv" 14 "strconv"
15 "strings" 15 "strings"
16 ) 16 )
17 17
18 // Error reports an error and the operation and URL that caused it. 18 // Error reports an error and the operation and URL that caused it.
19 type Error struct { 19 type Error struct {
20 Op string 20 Op string
21 URL string 21 URL string
22 Err error 22 Err error
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 // and password. 248 // and password.
249 // This functionality should only be used with legacy web sites. 249 // This functionality should only be used with legacy web sites.
250 // RFC 2396 warns that interpreting Userinfo this way 250 // RFC 2396 warns that interpreting Userinfo this way
251 // ``is NOT RECOMMENDED, because the passing of authentication 251 // ``is NOT RECOMMENDED, because the passing of authentication
252 // information in clear text (such as URI) has proven to be a 252 // information in clear text (such as URI) has proven to be a
253 // security risk in almost every case where it has been used.'' 253 // security risk in almost every case where it has been used.''
254 func UserPassword(username, password string) *Userinfo { 254 func UserPassword(username, password string) *Userinfo {
255 return &Userinfo{username, password, true} 255 return &Userinfo{username, password, true}
256 } 256 }
257 257
258 // ParseUserinfo parses a string with username and password
259 // separated by a ':' and returns a Userinfo. Note that
260 // the characters ':' in the username and password
261 // should be escaped, otherwise an error will be returned.
262 func ParseUserinfo(val string) (*Userinfo, error) {
263 parts := strings.Split(val, ":")
264 if len(parts) > 2 {
265 return nil, fmt.Errorf("invalid Userinfo: %q", val)
266 }
267 u, err := unescape(parts[0], encodeUserPassword)
268 if err != nil {
269 return nil, err
270 }
271 if len(parts) == 1 {
272 return User(u), nil
273 }
274 p, err := unescape(parts[1], encodeUserPassword)
275 if err != nil {
276 return nil, err
277 }
278 return UserPassword(u, p), nil
279 }
280
258 // The Userinfo type is an immutable encapsulation of username and 281 // The Userinfo type is an immutable encapsulation of username and
259 // password details for a URL. An existing Userinfo value is guaranteed 282 // password details for a URL. An existing Userinfo value is guaranteed
260 // to have a username set (potentially empty, as allowed by RFC 2396), 283 // to have a username set (potentially empty, as allowed by RFC 2396),
261 // and optionally a password. 284 // and optionally a password.
262 type Userinfo struct { 285 type Userinfo struct {
263 username string 286 username string
264 password string 287 password string
265 passwordSet bool 288 passwordSet bool
266 } 289 }
267 290
(...skipping 11 matching lines...) Expand all
279 } 302 }
280 303
281 // String returns the encoded userinfo information in the standard form 304 // String returns the encoded userinfo information in the standard form
282 // of "username[:password]". 305 // of "username[:password]".
283 func (u *Userinfo) String() string { 306 func (u *Userinfo) String() string {
284 s := escape(u.username, encodeUserPassword) 307 s := escape(u.username, encodeUserPassword)
285 if u.passwordSet { 308 if u.passwordSet {
286 s += ":" + escape(u.password, encodeUserPassword) 309 s += ":" + escape(u.password, encodeUserPassword)
287 } 310 }
288 return s 311 return s
289 }
290
291 // Implement GobEncoder/GobDecoder so UserInfo and URL objects can be serialized
292 func (u *Userinfo) GobEncode() ([]byte, error) {
293 buf := bytes.NewBuffer(nil)
294 ul := int16(len(u.username))
295 if err := binary.Write(buf, binary.BigEndian, ul); err != nil {
296 return nil, err
297 }
298 if _, err := buf.WriteString(u.username); err != nil {
299 return nil, err
300 }
301 if u.passwordSet {
302 pl := int16(len(u.password))
303 if err := binary.Write(buf, binary.BigEndian, pl); err != nil {
304 return nil, err
305 }
306 if _, err := buf.WriteString(u.password); err != nil {
307 return nil, err
308 }
309 } else {
310 if err := binary.Write(buf, binary.BigEndian, int16(-1)); err != nil {
311 return nil, err
312 }
313 }
314 return buf.Bytes(), nil
315 }
316
317 func (u *Userinfo) GobDecode(b []byte) error {
318 r := bytes.NewReader(b)
319 var ul int16
320 if err := binary.Read(r, binary.BigEndian, &ul); err != nil {
321 return err
322 }
323 if ul > 0 {
324 ub := make([]byte, int(ul))
325 if _, err := r.Read(ub); err != nil {
326 return err
327 }
328 u.username = string(ub)
329 }
330 var pl int16
331 if err := binary.Read(r, binary.BigEndian, &pl); err != nil {
332 return err
333 }
334 if pl >= 0 {
335 u.passwordSet = true
336 if pl > 0 {
337 pb := make([]byte, int(pl))
338 if _, err := r.Read(pb); err != nil {
339 return err
340 }
341 u.password = string(pb)
342 }
343 }
344 return nil
345 } 312 }
346 313
347 // Maybe rawurl is of the form scheme:path. 314 // Maybe rawurl is of the form scheme:path.
348 // (Scheme must be [a-zA-Z][a-zA-Z0-9+-.]*) 315 // (Scheme must be [a-zA-Z][a-zA-Z0-9+-.]*)
349 // If so, return scheme, path; else return "", rawurl. 316 // If so, return scheme, path; else return "", rawurl.
350 func getscheme(rawurl string) (scheme, path string, err error) { 317 func getscheme(rawurl string) (scheme, path string, err error) {
351 for i := 0; i < len(rawurl); i++ { 318 for i := 0; i < len(rawurl); i++ {
352 c := rawurl[i] 319 c := rawurl[i]
353 switch { 320 switch {
354 case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z': 321 case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 } else { 712 } else {
746 if strings.HasPrefix(result, "//") { 713 if strings.HasPrefix(result, "//") {
747 result = u.Scheme + ":" + result 714 result = u.Scheme + ":" + result
748 } 715 }
749 } 716 }
750 if u.RawQuery != "" { 717 if u.RawQuery != "" {
751 result += "?" + u.RawQuery 718 result += "?" + u.RawQuery
752 } 719 }
753 return result 720 return result
754 } 721 }
LEFTRIGHT

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