Ejemplo n.º 1
0
/*
 * Get version number
 */
static gint get_version(QQInfo *info)
{
	int ret = NO_ERR;
	Request *req = request_new();
	Response *rps = NULL;
	gint res = 0;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	request_set_uri(req, VERPATH);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGINPAGEHOST);

	Connection *con = connect_to_host(LOGINPAGEHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return NETWORK_ERR;
	}
	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);
	const gchar *retstatus = rps -> status -> str;
	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
	
	gchar *lb, *rb;
	gchar *ms = rps -> msg -> str;
	lb = g_strstr_len(ms, -1, "(");
	if(lb == NULL){
		g_warning("Get version  error!! %s (%s, %d)",rps -> msg -> str
                                        , __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
	++lb;
	rb = g_strstr_len(ms, -1, ")");
	*rb = '\0';
	info -> version = g_string_new(lb);
	g_debug("Version: %s(%s, %d)", lb, __FILE__, __LINE__);
error:
	request_del(req);
	response_del(rps);
	return ret;
}
Ejemplo n.º 2
0
void dav_request_execute(DavServer *server, DavRequest *request) {
	dav_response_clear(server, request);

	/* check url */
	if (0 == request->url_path->len) {
		dav_response_error(server, request, 400);
		return;
	}

	if ('/' != request->url_path->str[0]) {
		/* only the OPTIONS method allows an url not starting with "/", and it must be "*", nothing else */
		if ('*' != request->url_path->str[0] || 1 != request->url_path->len || DAV_OPTIONS != request->method) {
			dav_response_error(server, request, 400);
			return;
		}
	}

	switch (request->method) {
	case DAV_OPTIONS:
		request_options(server, request);
		break;
	case DAV_PROPFIND:
		request_propfind(server, request);
		break;
	case DAV_PROPPATCH:
		request_proppatch(server, request);
		break;
	case DAV_MKCOL:
		request_mkcol(server, request);
		break;
	case DAV_GET:
	case DAV_HEAD:
		request_get_and_head(server, request);
		break;
	case DAV_DELETE:
		request_del(server, request);
		break;
	case DAV_PUT:
		request_put(server, request);
		break;
	case DAV_COPY:
	case DAV_MOVE:
	case DAV_LOCK:
	case DAV_UNLOCK:
		break;
	}

	if (0 == request->response_status) {
		dav_response_error(server, request, 500);
	}

	if (NULL != request->response_text) {
		g_string_append_printf(dav_response_get_header(server, request), "Content-Length: %" G_GOFFSET_FORMAT "\r\n", (goffset) request->response_text->len);
	} else if (NULL == request->response_filename && -1 == request->response_fd) {
		if (DAV_HEAD != request->method || 200 != request->response_status) {
			g_string_append_len(dav_response_get_header(server, request), CONST_STR_LEN("Content-Length: 0\r\n"));
		}
	}
}
Ejemplo n.º 3
0
static gint do_send_buddy_msg(QQInfo *info, QQSendMsg *msg, GError **err)
{
    GString *uin = msg -> to_uin;

    gint ret_code = 0;
	gint res = 0;
    gchar params[3000];
    g_debug("Send msg to %s!(%s, %d)", uin -> str, __FILE__, __LINE__);

    Request *req = request_new();
    Response *rps = NULL;
    request_set_method(req, "POST");
    request_set_version(req, "HTTP/1.1");
    request_set_uri(req, MSGFRIPATH);
    request_set_default_headers(req);
    request_add_header(req, "Host", MSGHOST);
    request_add_header(req, "Cookie", info -> cookie -> str);
    request_add_header(req, "Origin", "http://d.web2.qq.com");
    request_add_header(req, "Content-Type", 
            "application/x-www-form-urlencoded");
    request_add_header(req, "Referer"
            , "http://"MSGHOST"/proxy.html?v=20110331002&callback=2");
    GString *content;
    content = qq_sendmsg_contents_tostring(msg);
    g_snprintf(params, 3000, "r={\"to\":%s,\"face\":%s,"
                "%s,\"msg_id\":%s,"
                "\"clientid\":\"%s\",\"psessionid\":\"%s\"}"
                , uin -> str, msg -> face -> str
                , content -> str
                , msg -> msg_id -> str
                , info -> clientid -> str
                , info -> psessionid -> str);
    g_string_free(content, TRUE);
    gchar *euri = g_uri_escape_string(params, "=", FALSE);
    request_append_msg(req, euri, strlen(euri));
    g_free(euri);

    g_snprintf(params, 3000, "%u", (unsigned int)strlen(req -> msg -> str));
    request_add_header(req, "Content-Length", params);

    Connection *con = connect_to_host(MSGHOST, 80);
    if(con == NULL){
        g_warning("Can NOT connect to server!(%s, %d)"
                , __FILE__, __LINE__);
        request_del(req);
        return -1;
    }

    send_request(con, req);
    res = rcv_response(con, &rps);
    close_con(con);
    connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret_code = -1;
		goto error;
	}
    const gchar *retstatus = rps -> status -> str;
    json_t *json = NULL;
    if(g_strstr_len(retstatus, -1, "200") == NULL){
        /*
         * Maybe some error occured.
         */
        g_warning("Resoponse status is NOT 200, but %s (%s, %d)"
                , retstatus, __FILE__, __LINE__);
        ret_code = -1;
        goto error;
    }

    switch(json_parse_document(&json, rps -> msg -> str))
    {
    case JSON_OK:
        break;
    default:
        g_warning("json_parser_document: syntax error. (%s, %d)"
                , __FILE__, __LINE__);
    }

    json_t *val = json_find_first_label_all(json, "result");
    if(val != NULL){
        val = val -> child;
        if(g_strstr_len(val -> text, -1, "ok") == NULL){
            g_warning("Server return error. %s (%s, %d)"
                    , val -> text, __FILE__, __LINE__);
        }
    }else{
        g_warning("Server return: (%s, %d)%s", __FILE__, __LINE__
                , rps -> msg -> str);
    }
    json_free_value(&json);
error:
    request_del(req);
    response_del(rps);
    return ret_code;
}
Ejemplo n.º 4
0
static gint do_logout(QQInfo *info, GError **err)
{
    gint ret_code = 0;
	gint res = 0;
	g_debug("Logout... (%s, %d)", __FILE__, __LINE__);
	if(info -> psessionid == NULL || info -> psessionid -> len <= 0){
		g_warning("Need psessionid !!(%s, %d)", __FILE__, __LINE__);
		return -1;
	}

	gchar params[300];
	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, LOGOUTPATH"?clientid=%s&psessionid=%s&t=%ld"
			, info -> clientid -> str
			, info -> psessionid -> str, get_now_millisecond());
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGOUTHOST);
	request_add_header(req, "Cookie", info -> cookie -> str);
	request_add_header(req, "Referer", REFERER);

	Connection *con = connect_to_host(LOGOUTHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return -1;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret_code = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		/*
		 * Maybe some error occured.
		 */
		g_warning("Resoponse status is NOT 200, but %s (%s, %d)"
				, retstatus, __FILE__, __LINE__);
        ret_code = -1;
		goto error;
	}

	json_t *json = NULL;
	switch(json_parse_document(&json, rps -> msg -> str))
	{
	case JSON_OK:
		break;
	default:
		g_warning("json_parser_document: syntax error. (%s, %d)"
				, __FILE__, __LINE__);
        ret_code = -1;
		goto error;
	}

	json_t *retcode, *result;
	retcode = json_find_first_label_all(json, "retcode");
	result = json_find_first_label_all(json, "result");
	if(retcode != NULL && result != NULL){
		if(g_strstr_len(result -> child -> text, -1, "ok") != NULL){
			g_debug("Logout ok!(%s, %d)", __FILE__, __LINE__);
            ret_code = 0;
		}
	}else{
		g_debug("(%s, %d)%s", __FILE__, __LINE__, rps -> msg -> str);
	}
	
	json_free_value(&json);
error:
	request_del(req);
	response_del(rps);
	return ret_code;
}
Ejemplo n.º 5
0
/*
 * Get the psessionid.
 *
 * This function is the last step of loginning
 */
static int get_psessionid(QQInfo *info)
{
	int ret = NO_ERR;
	gint res = 0;
	if(info -> ptwebqq == NULL || info -> ptwebqq -> len <= 0){
		g_warning("Need ptwebqq!!(%s, %d)", __FILE__, __LINE__);
		return PARAMETER_ERR;
	}
	
	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "POST");
	request_set_version(req, "HTTP/1.1");
	request_set_uri(req, PSIDPATH);
	request_set_default_headers(req);
	request_add_header(req, "Host", PSIDHOST);
	request_add_header(req, "Cookie2", "$Version=1");
	request_add_header(req, "Referer"
			, "http://d.web2.qq.com/proxy.html?v=20101025002");
	GString *clientid = generate_clientid();
	info -> clientid = clientid;
	g_debug("clientid: %s", clientid -> str);

	gchar* msg = g_malloc(500);
	g_snprintf(msg, 500, "{\"status\":\"%s\",\"ptwebqq\":\"%s\","
			"\"passwd_sig\":""\"\",\"clientid\":\"%s\""
			", \"psessionid\":null}"
			, info -> me -> status -> str, info -> ptwebqq -> str
			, clientid -> str);

	gchar *escape = g_uri_escape_string(msg, NULL, FALSE);
	g_snprintf(msg, 500, "r=%s", escape);
	g_free(escape);

	request_append_msg(req, msg, strlen(msg));
	gchar cl[10];
	g_sprintf(cl, "%u", (unsigned int)strlen(msg));
	request_add_header(req, "Content-Length", cl);
	request_add_header(req, "Content-Type"
			, "application/x-www-form-urlencoded");
	g_free(msg);

	gchar *cookie = g_malloc(2000);
	gint idx = 0;
	if(info -> ptvfsession != NULL){
		idx += g_snprintf(cookie + idx, 2000 - idx, "ptvfsession=%s; "
				, info -> ptvfsession -> str);
	}
	idx += g_snprintf(cookie + idx, 2000 - idx, "%s"
			, info -> cookie -> str);
	request_add_header(req, "Cookie", cookie);
	g_free(cookie);

	Connection *con = connect_to_host(PSIDHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return NETWORK_ERR;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	json_t *json = NULL;
	switch(json_parse_document(&json, rps -> msg -> str))
	{
	case JSON_OK:
		break;
	default:
		g_warning("json_parser_document: syntax error. (%s, %d)"
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	json_t *val;
	val = json_find_first_label_all(json, "retcode");
	if(val -> child -> text[0] != '0'){
		g_warning("Server return code %s(%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
	val = json_find_first_label_all(json, "seskey");
	if(val != NULL){
		g_debug("seskey: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		info -> seskey = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "cip");
	if(val != NULL){
		info -> cip = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "index");
	if(val != NULL){
		info -> index = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "port");
	if(val != NULL){
		info -> port = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "status");
	{
		g_debug("status: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
	}
	val = json_find_first_label_all(json, "vfwebqq");
	if(val != NULL){
		g_debug("vfwebqq: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		info -> vfwebqq = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "psessionid");
	if(val != NULL){
		g_debug("psessionid: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		info -> psessionid = g_string_new(val -> child -> text);
	}else{
		g_debug("Can not find pesssionid!(%s, %d): %s"
				, __FILE__, __LINE__, rps -> msg -> str);
	}

error:
	json_free_value(&json);	
	close_con(con);
	connection_free(con);
	request_del(req);
	response_del(rps);
	return ret;
}
Ejemplo n.º 6
0
/*
 * Check if we need input the verify code.
 * The result is stored in info.
 *
 * return -1 if error ocurs or return 0
 */
static gint check_verify_code(QQInfo *info)
{
	g_debug("Check veriry code...(%s, %d)", __FILE__, __LINE__);
	gint ret = 0;
	gchar params[300];

	Request *req = request_new();
	Response *rps = NULL;
	int res = 0;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, VCCHECKPATH"?uin=%s&appid="APPID"&r=%.16f"
			, info -> me -> uin -> str, g_random_double());
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGINHOST);

	Connection *con = connect_to_host(LOGINHOST, 80);

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	/*
	 * The http message body has two format:
	 *
	 * 	ptui_checkVC('1','9ed32e3f644d968809e8cbeaaf2cce42de62df
	 * 					ee12c14b74');
	 * 	ptui_checkVC('0','!LOB');
	 * The former means we need verify code image and the second 
	 * parameter is vc_type.
	 * The later means we don't need the verify code image. The second
	 * parameter is the verify code. The vc_type is in the header 
	 * "Set-Cookie".
	 */

	gchar *c, *s;
       	s = rps -> msg -> str;
	if(g_strstr_len(s, -1, "ptui_checkVC") == NULL){
		g_warning("Get vc_type error!(%s, %d)", __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	g_debug("check vc return: %s(%s, %d)", s, __FILE__, __LINE__);
	c = g_strstr_len(s, -1, "'");
	++c;
	if(*c == '0'){
		/*
		 * We got the verify code.
		 */
		info -> need_vcimage = FALSE;
		s = c;
		c = g_strstr_len(s, -1, "'");
		s = c + 1; 
		c = g_strstr_len(s, -1, "'");
		s = c + 1;
		c = g_strstr_len(s, -1, "'");
		*c = '\0';
		info -> verify_code = g_string_new(s);
		g_debug("Verify code : %s (%s, %d)", info -> verify_code -> str
				, __FILE__, __LINE__);
		/*
		 * We need get the ptvfsession from the header "Set-Cookie"
		 */
		info -> ptvfsession = get_cookie(rps, "ptvfsession");
	}else if(*c == '1'){
		/*
		 * We need get the verify image.
		 */
		info -> need_vcimage = TRUE;
		s = c;
		c = g_strstr_len(s, -1, "'");
		s = c + 1;
		c = g_strstr_len(s, -1, "'");
		s = c + 1;
		c = g_strstr_len(s, -1, "'");
		*c = '\0';
		info -> vc_type = g_string_new(s);
		g_debug("We need verify code image! vc_type: %s (%s, %d)"
				, info -> vc_type -> str, __FILE__, __LINE__);
	}else{
		g_warning("Unknown return value!(%s, %d)", __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
error:
	request_del(req);
	response_del(rps);
	return ret;
}
Ejemplo n.º 7
0
/*
 * Get ptca and skey
 * return the status returned by the server.
 * If error occured, store the error message in info -> errmsg
 */
static gint get_ptcz_skey(QQInfo *info, const gchar *p)
{
	gint ret = 0;
	gint res = 0;
	gchar params[300];

	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, LOGINPATH"?u=%s&p=%s&verifycode=%s&webqq_type=40&"
			"remember_uin=0&aid="APPID"&login2qq=1&u1=%s&h=1&"
			"ptredirect=0&ptlang=2052&from_ui=1&pttype=1"
			"&dumy=&fp=loginerroralert&action=4-30-764935&mibao_css=m_webqq"
			, info -> me -> uin -> str, p, info -> verify_code -> str
			, LOGIN_S_URL);
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGINHOST);
	request_add_header(req, "Referer", "http://ui.ptlogin2.qq.com/cgi-bin/"
						"login?target=self&style=4&appid=1003903&enable_ql"
						"ogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.c"
						"om%2Floginproxy.html%3Flogin_level%3D3"
						"&f_url=loginerroralert");
	if(info -> ptvfsession != NULL){
		g_sprintf(params, "ptvfsession=%s; "
				, info -> ptvfsession -> str);
		request_add_header(req, "Cookie", params);
	}

	Connection *con = connect_to_host(LOGINHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return -1;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = -1;
		goto error;
	}

	gint status;
	gchar *sbe = g_strstr_len(rps -> msg -> str, -1, "'");
	++sbe;
	gchar *sen = g_strstr_len(sbe, -1, "'");
	*sen = '\0';
	status = strtol(sbe, NULL, 10);
	*sen = '\'';
	ret = status;
	if(status == 0){
		g_debug("Success.(%s, %d)", __FILE__, __LINE__);
	}else if(status == 1){
		g_warning("Server busy! Please try again.(%s, %d)"
				, __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Server busy!");
		goto error;
	}else if(status == 2){
		g_warning("Out of date QQ number!(%s, %d)"
				, __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Out of date QQ number.");
		goto error;
	}else if(status == 3){
		g_warning("Wrong password!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Wrong password.");
		goto error;
	}else if(status == 4){
		g_warning("Wrong verify code!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Wrong verify code.");
		goto error;
	}else if(status == 5){
		g_warning("Verify failed!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Verify failed.");
		goto error;
	}else if(status == 6){
		g_warning("You may need to try login again.(%s, %d)", __FILE__
				, __LINE__);
		//g_sprintf(info -> errmsg, "Please try again.");
		goto error;
	}else if(status == 7){
		g_warning("Wrong input!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Wrong input.");
		goto error;
	}else if(status == 8){
		g_warning("Too many logins on this IP. Please try again.(%s, %d)"
				, __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Too many logins on this IP.");
		goto error;
	}else{
		g_warning("Server response message:(%s, %d)\n\t%s"
				, __FILE__, __LINE__, rps -> msg -> str);
		goto error;
	}

	info -> ptcz = get_cookie(rps, "ptcz");
	info -> skey = get_cookie(rps, "skey");
	info -> ptwebqq = get_cookie(rps, "ptwebqq");
	info -> ptuserinfo = get_cookie(rps, "ptuserinfo");
    info -> uin = get_cookie(rps, "uin");
    info -> ptisp = get_cookie(rps, "ptisp");
    info -> pt2gguin = get_cookie(rps, "pt2gguin");
	//sotre the cookie
	info -> cookie = g_string_new("");
    g_string_append(info -> cookie, "ptcz=");
    g_string_append(info -> cookie, info -> ptcz -> str);
    g_string_append(info -> cookie, ";skey=");
    g_string_append(info -> cookie, info -> skey -> str);
    g_string_append(info -> cookie, ";ptwebqq=");
    g_string_append(info -> cookie, info -> ptwebqq -> str);
    g_string_append(info -> cookie, ";ptuserinfo=");
    g_string_append(info -> cookie, info -> ptuserinfo -> str);
    g_string_append(info -> cookie, ";uin=");
    g_string_append(info -> cookie, info -> uin -> str);
    g_string_append(info -> cookie, ";ptisp=");
    g_string_append(info -> cookie, info -> ptisp -> str);
    g_string_append(info -> cookie, ";pt2gguin=");
    g_string_append(info -> cookie, info -> pt2gguin -> str);
error:
	request_del(req);
	response_del(rps);
	return ret;
}
Ejemplo n.º 8
0
/*
 * Get the verify code image form the server
 */
static gint get_vc_image(QQInfo *info)
{
	if(info -> vc_type == NULL || info -> vc_type -> len <=0){
		g_warning("Need vc_type!!(%s, %d)", __FILE__, __LINE__);
		return PARAMETER_ERR;
	}
	gint ret = 0;
	gchar params[500];
	gint res = 0;

	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, IMAGEPATH"?aid="APPID"&r=%.16f&uin=%s&vc_type=%s"
			, g_random_double(), info -> me -> uin -> str
			, info -> vc_type -> str);
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", IMAGEHOST);

	Connection *con = connect_to_host(IMAGEHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return NETWORK_ERR;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	info -> vc_image_data = g_string_new(NULL);
	g_string_append_len(info -> vc_image_data, rps -> msg -> str
				, rps -> msg -> len);
    info -> vc_image_size = rps -> msg -> len;

	gchar *ct = response_get_header_chars(rps, "Content-Type");
	gchar *vc_ftype = g_strstr_len(ct, -1, "image/");
	g_debug("vc content type: %s(%s, %d)", vc_ftype, __FILE__, __LINE__);
	if(vc_ftype == NULL){
		g_warning("Unknown verify code image file type!(%s, %d)"
				, __FILE__, __LINE__);
		g_string_free(info -> vc_image_data, TRUE);
		info -> vc_image_data = NULL;
		ret = NETWORK_ERR;
		goto error;

	}
	vc_ftype += (sizeof("image/") - 1);
	g_debug("Verify code image file type: %s len %d (%s, %d)", vc_ftype
                    , info -> vc_image_size, __FILE__, __LINE__);
	g_strstrip(vc_ftype);
	info -> vc_image_type = g_string_new(vc_ftype);

error:
	request_del(req);
	response_del(rps);
	return ret;
}