void start_curl() {
		state = kDownloading;
		curl = curl_easy_init();
		//assert(direct_ip.size());
		std::string actual_url = redirect_url.size() ? redirect_url:url;
		char buf[1024];
		sprintf(buf,"%s://%s%s%s",
					extract_proto(actual_url).c_str(),
					direct_ip.c_str(),
					extract_port(actual_url).c_str(),
					extract_path(actual_url).c_str());
		curl_easy_setopt(curl, CURLOPT_URL, buf);
		sprintf(buf,"Host: %s%s",extract_host(actual_url).c_str(),extract_port(actual_url).c_str());
		headers = curl_slist_append(headers,buf);
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Request::GotData);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)this);
		curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-airplay-agent/1.0");
		curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT, 15);
		curl_easy_setopt(curl,CURLOPT_TIMEOUT, 30);
		curl_easy_setopt(curl,CURLOPT_NOPROGRESS, 0);
		curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION, 0);

		curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION, Request::GotHeaderStatic);
		curl_easy_setopt(curl,CURLOPT_HEADERDATA, this);

		curl_easy_setopt(curl,CURLOPT_PROGRESSFUNCTION, Request::GotProgressStatic);
		curl_easy_setopt(curl,CURLOPT_PROGRESSDATA, (void *)this);
		//curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
		if( curlsh )
			curl_easy_setopt(curl,CURLOPT_SHARE,curlsh);
		if( curlm )
			curl_multi_add_handle(curlm, curl);
	}
void load_database_contexts(Context_Map* context_map)
{
    int prefix_mask {};
    
    std::ifstream buf;
    buf.open(DBCONFIG_FILE);
    assert(buf.is_open());

    std::string line {};
    
    while (!buf.eof())
    {
        getline(buf,line);
        if (ignore_line(line)) continue;
        else if (str_contains(line,'@'))
        {
            int port {};
            std::string host {};
            int db_num {};
            
            // Complete at 00000111 (7)
            // One bit is set each time one of the above is found.
            // This allows for any number of newlines or comments.
            uint8_t completion {};
            Prefix p {match_prefix(prefix_mask, line)};
            while ((completion != 7) && !buf.eof())
            {
                getline(buf,line);
                if (ignore_line(line)) continue;
                else if (str_contains(line,"port"))
                {
                    port = extract_integer(line);
                    completion |= 1;
                }
                else if (str_contains(line, "number"))
                {
                    db_num = extract_integer(line);
                    completion |= 2;
                }
                else if (str_contains(line, "host"))
                {
                    host = extract_host(line);
                    completion |= 4;
                }
            }
            assert(completion==7);
            Redis::Context* c = new Redis::Context();
            c->port = port;
            c->host = host;
            c->db_num = db_num;
            context_map->set(p,c);
            assert(context_map->get(p));
        }
    }
    buf.close();
    assert(prefix_mask >= max_prefix_mask);
    assert(context_map);
}
Exemple #3
0
int dash_eval(char *line, char *std_input, char *origin)
{
  if (line == NULL)
    return 1;

  int num_tokens;
  char **tokens = str_split(line, " ", &num_tokens);
  char *token;
  int i;
  int remote_pipe_pos = -1;

  for (i = 0; i < num_tokens; i++) {
    if (strcmp(tokens[i], REMOTE_PIPE) == 0) {
      remote_pipe_pos = i;
      break;
    }
  }

  if (remote_pipe_pos == -1) // No remote pipes
  {
    char *msg_data = dash_exec_scmd(tokens, remote_pipe_pos + 1, num_tokens, std_input);
    if (std_input == NULL) {
      printf("%s", msg_data);
      return 1;
    }
    else { // Send to origin
      char *fio_msg = dashp_fio(msg_data);
      send_to_host(fio_msg, origin);
      return 1;
    }
  }
  else // Remote pipe at remote_pipe_pos
  {
    char *subcommand = join_strings(tokens, " ", remote_pipe_pos+1, num_tokens);
    char *remotehost = extract_host(subcommand);
    char *maincommand = join_strings(tokens, " ", 0, remote_pipe_pos);
    char *msg_data = dash_exec_scmd(tokens, 0, remote_pipe_pos, std_input);
    char *send_msg;
    if (std_input == NULL) {
      // TODO: MAKE IP ADDRESS FUNCTION WORK!
      char *fin_remote_host = (char *) malloc (strlen(remotehost) + 1);
      strcat(fin_remote_host, remotehost);
      strcat(fin_remote_host, ":");
      remove_substring(subcommand, fin_remote_host);
      free (fin_remote_host);
      subcommand[strlen(subcommand)-1] = '\0';
      send_msg = dashp_pip(msg_data, "127.0.0.1", subcommand);
    }
    else {
      send_msg = dashp_pip(msg_data, origin, subcommand);
    }
    send_to_host(send_msg, remotehost);
    printf("Sent");
    return 2;
  }
}
	void start_resolve() {
		if( ares ) {
			ares_destroy(ares);
			ares = 0;
		}
		state = kResolving;
		std::string actual_url = redirect_url.size() ? redirect_url:url;
		std::string host = extract_host(actual_url);
		std::string res = dns_cache->get_ent(host);
		if( !res.size() ) {
			ares_init(&ares);
			ares_gethostbyname(ares,host.c_str(),AF_INET,Request::GotResolveStatic,this);
		} else {
			char buf[1024];
			sprintf(buf,"%d.%d.%d.%d",res[0],res[1],res[2],res[3]);
			direct_ip = buf;
			state = kStartDownload;
		}
	}
	void GotResolve(int status, int timeouts, struct hostent *hostent)
	{
		switch(status) {
			case ARES_SUCCESS:
				{
					char buf[1024];
					sprintf(buf,"%d.%d.%d.%d",hostent->h_addr[0],hostent->h_addr[1],hostent->h_addr[2],hostent->h_addr[3]);
					direct_ip = buf;
					state = kStartDownload;
					std::string actual_url = redirect_url.size() ? redirect_url:url;
					dns_cache->add_ent(extract_host(actual_url),hostent);
			    }
				break;
			case ARES_EDESTRUCTION:
				break;
			case ARES_ECANCELLED:
				finish_error(status,"ARES_ECANCELLED");
				break;
			case ARES_ETIMEOUT:
				finish_error(status,"ARES_ETIMEOUT");
				break;
			case ARES_ENOTIMP:
				finish_error(status,"ARES_ENOTIMP");
				break;
			case ARES_EBADNAME:
				finish_error(status,"ARES_EBADNAME");
				break;
			case ARES_ENOTFOUND:
				finish_error(status,"ARES_ENOTFOUND");
				break;
			case ARES_ENOMEM:
				finish_error(status,"ARES_ENOMEM");
				break;
			default:
				finish_error(status,"ARES - UNKNOWN!");
				break;
		}
	}
Exemple #6
0
/* 处理客户端的连接 */
void handle_client(int client_sock, struct sockaddr_in client_addr)
{
    int is_http_tunnel = 0; 
    if(strlen(remote_host) == 0) /* 未指定远端主机名称从http 请求 HOST 字段中获取 */
    {
        
        #ifdef DEBUG
        LOG(" ============ handle new client ============\n");
        LOG(">>>Header:%s\n",header_buffer);
        #endif
        
        if(read_header(client_sock,header_buffer) < 0)
        {
            LOG("Read Http header failed\n");
            return;
        } else 
        {
            char * p = strstr(header_buffer,"CONNECT"); /* 判断是否是http 隧道请求 */
            if(p) 
            {
                LOG("receive CONNECT request\n");
                is_http_tunnel = 1;
            }

            if(strstr(header_buffer,"GET /mproxy") >0 ) 
            {
                LOG("====== hand mproxy info request ====");
                //返回mproxy的运行基本信息
                hand_mproxy_info_req(client_sock,header_buffer);

                return; 
            }

            if(extract_host(header_buffer) < 0) 
            {
                LOG("Cannot extract host field,bad http protrotol");
                return;
            }
            LOG("Host:%s port: %d io_flag:%d\n",remote_host,remote_port,io_flag);

        }
    }

    if ((remote_sock = create_connection()) < 0) {
        LOG("Cannot connect to host [%s:%d]\n",remote_host,remote_port);
        return;
    }

    if (fork() == 0) { // 创建子进程用于从客户端转发数据到远端socket接口

        if(strlen(header_buffer) > 0 && !is_http_tunnel) 
        {
            forward_header(remote_sock); //普通的http请求先转发header
        } 
        
        forward_data(client_sock, remote_sock);
        exit(0);
    }

    if (fork() == 0) { // 创建子进程用于转发从远端socket接口过来的数据到客户端

        if(io_flag == W_S_ENC)
        {
            io_flag = R_C_DEC; //发送请求给服务端进行编码,读取服务端的响应则进行解码
        } else if (io_flag == R_C_DEC)
        {
             io_flag = W_S_ENC; //接收客户端请求进行解码,那么响应客户端请求需要编码
        }

        if(is_http_tunnel)
        {
            send_tunnel_ok(client_sock);
        } 

        forward_data(remote_sock, client_sock);
        exit(0);
    }

    close(remote_sock);
    close(client_sock);
}