1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_BASE_HTTPCOMMON_INL_H__ 12 #define WEBRTC_BASE_HTTPCOMMON_INL_H__ 13 14 #include "webrtc/base/common.h" 15 #include "webrtc/base/httpcommon.h" 16 17 namespace rtc { 18 19 /////////////////////////////////////////////////////////////////////////////// 20 // Url 21 /////////////////////////////////////////////////////////////////////////////// 22 23 template<class CTYPE> 24 void Url<CTYPE>::do_set_url(const CTYPE* val, size_t len) { 25 if (ascnicmp(val, "http://", 7) == 0) { 26 val += 7; len -= 7; 27 secure_ = false; 28 } else if (ascnicmp(val, "https://", 8) == 0) { 29 val += 8; len -= 8; 30 secure_ = true; 31 } else { 32 clear(); 33 return; 34 } 35 const CTYPE* path = strchrn(val, len, static_cast<CTYPE>('/')); 36 if (!path) { 37 path = val + len; 38 } 39 size_t address_length = (path - val); 40 do_set_address(val, address_length); 41 do_set_full_path(path, len - address_length); 42 } 43 44 template<class CTYPE> 45 void Url<CTYPE>::do_set_address(const CTYPE* val, size_t len) { 46 if (const CTYPE* at = strchrn(val, len, static_cast<CTYPE>('@'))) { 47 // Everything before the @ is a user:password combo, so skip it. 48 len -= at - val + 1; 49 val = at + 1; 50 } 51 if (const CTYPE* colon = strchrn(val, len, static_cast<CTYPE>(':'))) { 52 host_.assign(val, colon - val); 53 // Note: In every case, we're guaranteed that colon is followed by a null, 54 // or non-numeric character. 55 port_ = static_cast<uint16>(::strtoul(colon + 1, NULL, 10)); 56 // TODO: Consider checking for invalid data following port number. 57 } else { 58 host_.assign(val, len); 59 port_ = HttpDefaultPort(secure_); 60 } 61 } 62 63 template<class CTYPE> 64 void Url<CTYPE>::do_set_full_path(const CTYPE* val, size_t len) { 65 const CTYPE* query = strchrn(val, len, static_cast<CTYPE>('?')); 66 if (!query) { 67 query = val + len; 68 } 69 size_t path_length = (query - val); 70 if (0 == path_length) { 71 // TODO: consider failing in this case. 72 path_.assign(1, static_cast<CTYPE>('/')); 73 } else { 74 ASSERT(val[0] == static_cast<CTYPE>('/')); 75 path_.assign(val, path_length); 76 } 77 query_.assign(query, len - path_length); 78 } 79 80 template<class CTYPE> 81 void Url<CTYPE>::do_get_url(string* val) const { 82 CTYPE protocol[9]; 83 asccpyn(protocol, ARRAY_SIZE(protocol), secure_ ? "https://" : "http://"); 84 val->append(protocol); 85 do_get_address(val); 86 do_get_full_path(val); 87 } 88 89 template<class CTYPE> 90 void Url<CTYPE>::do_get_address(string* val) const { 91 val->append(host_); 92 if (port_ != HttpDefaultPort(secure_)) { 93 CTYPE format[5], port[32]; 94 asccpyn(format, ARRAY_SIZE(format), ":%hu"); 95 sprintfn(port, ARRAY_SIZE(port), format, port_); 96 val->append(port); 97 } 98 } 99 100 template<class CTYPE> 101 void Url<CTYPE>::do_get_full_path(string* val) const { 102 val->append(path_); 103 val->append(query_); 104 } 105 106 template<class CTYPE> 107 bool Url<CTYPE>::get_attribute(const string& name, string* value) const { 108 if (query_.empty()) 109 return false; 110 111 std::string::size_type pos = query_.find(name, 1); 112 if (std::string::npos == pos) 113 return false; 114 115 pos += name.length() + 1; 116 if ((pos > query_.length()) || (static_cast<CTYPE>('=') != query_[pos-1])) 117 return false; 118 119 std::string::size_type end = query_.find(static_cast<CTYPE>('&'), pos); 120 if (std::string::npos == end) { 121 end = query_.length(); 122 } 123 value->assign(query_.substr(pos, end - pos)); 124 return true; 125 } 126 127 /////////////////////////////////////////////////////////////////////////////// 128 129 } // namespace rtc 130 131 #endif // WEBRTC_BASE_HTTPCOMMON_INL_H__ 132