示例#1
0
	/** UrlEncode **/
	String* UrlEncode::Encode(const char* src, const int64_t len){
		if(!src){
			return 0;
		}
		// prepare
		BinaryCoder<1024> coder;
		int64_t real_len =len;
		if(len < 0){
			real_len =strlen(src);
		}
		// encode
		for(int64_t i=0; i<real_len; ++i){
			const char ch =src[i];
			if(isalnum(ch) || ch=='.' || ch=='-' || ch=='_' || ch=='~'){
				coder.append(&ch, 1);
			}
			else{
				char sz[3];
				sprintf(sz, "%%%02X", (unsigned char)ch);
				coder.append(sz, sizeof(sz));
			}
		}
		// return
		if(coder.size() == 0){
			return String::New();
		}
		else{
			return String::New(coder.c_str(), coder.size());
		}
	}
示例#2
0
	/** helper **/
	bool Url::ParseQuery(String* query_str, Hash* tb){
		// prepare
		BinaryCoder<1024> coder;
		coder.append(query_str);
		coder.appendNull();
		char* save_ptr =0;
		char* query_string =coder.c_str();

		// split
		const char* szitem=strtok_r(query_string, "&", &save_ptr);
		while(szitem){
			// split key value
			const char* cursor =strchr(szitem, '=');
			const int64_t pos =cursor ? cursor-szitem : -1;
			if(pos > 0){
				const char* szkey =szitem;
				const char* szvalue =szitem + pos + 1;
				if(strchr(szvalue, '=') != 0){
					return false;
				}
				String* key =UrlEncode::Decode(szkey, pos);
				String* value =UrlEncode::Decode(szvalue, -1);
				tb->set(key, value);
				// DEBUG("%s=%s", key->c_str(), value->c_str());
			}
			else if(pos<0 && *szitem){
				String* key =UrlEncode::Decode(szitem, -1);
				String* value =STR("true");
				tb->set(key, value);
				// DEBUG("%s=%s", key->c_str(), value->c_str());
			}

			// next key value item
			szitem =strtok_r(0, "&", &save_ptr);
		}
		return true;
	}
示例#3
0
	String* UrlEncode::Decode(const char* code, const int64_t len){
		if(!code){
			return 0;
		}
		// prepare
		BinaryCoder<1024> coder;
		int64_t real_len =len;
		if(len < 0){
			real_len =strlen(code);
		}
		// encode
		for(int64_t i=0; i<real_len; ++i){
			int ch =code[i];
			if(isalnum(ch) || ch=='.' || ch=='-' || ch=='_' || ch=='~'){
				const uint8_t x =static_cast<uint8_t>(ch);
				coder.append(&x, 1);
			}
			else if(ch == '%'){
				if(1 != sscanf(code+i, "%%%2X", &ch)){
					ERROR("invalid url code");
					return 0;
				}
				const uint8_t x =static_cast<uint8_t>(ch);
				coder.append(&x, sizeof(x));
				i+=2;
			}
			else{
					puts(code);
				ERROR("invalid url code");
				return 0;
			}
		}
		// return
		if(coder.size() == 0){
			return String::New();
		}
		else{
			return String::New(coder.c_str(), coder.size());
		}
	}
示例#4
0
	String* HttpCookie::build(const bool client){
		if(!m_Name || m_Name->empty() || !m_Value || m_Value->empty()){
			WARN("build cookie failed, name or value is invalid");
			return 0;
		}
		BinaryCoder<1024> coder;
		if(client){
			coder.append("Cookie: ", 8);
		}
		else{
			coder.append("Set-Cookie: ", 12);
		}

		// name = value
		coder.append(m_Name);
		coder.append("=", 1);
		coder.append(m_Value);

		if(!client){
			// domain
			if(m_Domain){
				coder.append("; domain=", 9);
				coder.append(m_Domain);
			}

			// path
			if(m_Domain){
				coder.append("; path=", 7);
				coder.append(m_Path);
			}

			// secure
			if(m_Secure){
				coder.append("; secure", 8);
			}

			// HttpOnly
			if(m_HttpOnly){
				coder.append("; HttpOnly", 10);
			}

			// max age
			if(m_MaxAge > 0){
				coder.append("; max-age=", 10);
				coder.append(String::Format("%lld", (long long)m_MaxAge));
			}

			// expires
			if(m_ExpireTime){
				coder.append("; expires=", 10);
				coder.append(m_ExpireTime);
			}
		}
		return String::New(coder.c_str(), coder.size());
	}
示例#5
0
	bool HttpRespond::flush(){
		// check
		if(m_requestor == 0){
			WARN("http flush failed, requestor is null");
			return false;
		}

		//// build data
		BinaryCoder<4096> coder;

		/// head line
		// version
		if(m_version){
			coder.append(m_version);
		}
		else{
			coder.append("HTTP/1.1");
		}
		coder.append(" ");
		// code
		coder.append(String::Format("%lld", (long long)m_code));
		coder.append(" ");
		// msg
		coder.append(_code_to_msg(m_code));
		coder.append("\r\n");

		/// header
	  	if(!m_header_tb->has("Content-Type")){
			coder.append("Content-Type: text/html\r\n");
		}
	  	if(!m_header_tb->has("Content-Length")){
			coder.append(String::Format("Content-Length: %lld\r\n", (long long)m_content->size()));
		}
		HashIterator* it =static_cast< HashIterator* >(m_header_tb->iterator());
		while(it->next()){
			if(String* name =dynamic_cast< String* >(it->getKey())){
				if(String* value =dynamic_cast< String* >(it->getValue())){
					coder.append(name);
					coder.append(": ");
					coder.append(value);
					coder.append("\r\n");
				}
			}
		}
		it =static_cast< HashIterator* >(m_cookie_tb->iterator());
		while(it->next()){
			if(dynamic_cast< String* >(it->getKey())){
				if(HttpCookie* cookie =dynamic_cast< HttpCookie* >(it->getValue())){
					if(String* str =cookie->build(false)){
						coder.append(str);
						coder.append("\r\n");
					}
				}
			}
		}
		coder.append("\r\n");

		/// content
		if(m_content->size() > 0){
			coder.append(m_content->c_str(), m_content->size());
		}

		//// send
		const bool ok =m_requestor->send(coder.c_str(), coder.size());

		//// clear
		CLEAN_POINTER(m_version);
		m_code =200;
		CLEAN_POINTER(m_msg);
		m_header_tb->clear();
		m_cookie_tb->clear();
		m_content->clear();

		//// post process
		if(!ok){
			close();
		}
		m_auto_flush =false;
		return ok;
	}
示例#6
0
	bool Url::_build(String* protocol, String* auth, String* host, String* path, String* query_string, Hash* query, String* fragment){
		// clean
		clean();

		// check
		if(path && path->size() && !path->hasPrefix("/")){
			return false;
		}

		// make url
		BinaryCoder<1024> coder;

		if(protocol && protocol->size()){
			ASSIGN_POINTER(m_protocol, protocol);
			coder.append(protocol);
			coder.append("://", 3);
		}
		if(auth && auth->size()){
			ASSIGN_POINTER(m_auth, auth);
			coder.append(auth);
			coder.append("@", 1);
		}
		if(host && host->size()){
			ASSIGN_POINTER(m_host, host);
			coder.append(host);
		}
		if(path && path->size()){
			ASSIGN_POINTER(m_path, path);
			coder.append(path);
		}
		if(query_string && query_string->size()){
			ASSIGN_POINTER(m_query_string, query_string);
			ASSIGN_POINTER(m_query, SafeNew<Hash>());
			if(!ParseQuery(m_query_string, m_query)){
				clean();
				return false;
			}
			coder.append("?", 1);
			coder.append(m_query_string);
		}
		else if(query && query->size()){
			ASSIGN_POINTER(m_query, query);
			// make query string
			BinaryCoder<1024> sub_coder;
			HashIterator* it =static_cast< HashIterator* >(query->iterator());
			while(it->next()){
				String* key =static_cast< String* >(it->getKey());
				String* val =static_cast< String* >(it->getValue());
				if(sub_coder.size() > 0){
					sub_coder.append("&", 1);
				}
				sub_coder.append(UrlEncode::Encode(key));
				sub_coder.append("=", 1);
				sub_coder.append(UrlEncode::Encode(val));
			}
			// set
			ASSERT(sub_coder.size());
			ASSIGN_POINTER(m_query_string, String::New(sub_coder.c_str(), sub_coder.size()));
			coder.append("?", 1);
			coder.append(m_query_string);
		}
		if(fragment && fragment->size()){
			ASSIGN_POINTER(m_fragment, fragment);
			coder.append("#", 1);
			coder.append(fragment);
		}
		ASSIGN_POINTER(m_url, String::New(coder.c_str(), coder.size()));
		return true;
	}