/*调用用户注册的验证码函数来让用户识别验证码图片,并让用户输入识别结果*/ PcsRes pcs_get_captcha(Pcs handle, const char *code_string, char *captcha, int captchaSize) { struct pcs *pcs = (struct pcs *)handle; char *url, *img; size_t imgsz; captcha[0] = '\0'; if (!pcs->captcha_func) { pcs_set_errmsg(handle, "No captch function, please regist the function by call pcs_setopt(handle, PCS_OPTION_CAPTCHA_FUNCTION, pFun)."); return PCS_NO_CAPTCHA_FUNC; } url = pcs_utils_sprintf(URL_CAPTCHA "%s", code_string); img = pcs_http_get_raw(pcs->http, url, PcsTrue, &imgsz); if (!img) { pcs_set_errmsg(handle, "Can't get captch image from the server. url: %s. Error message: %s", url, pcs_http_strerror(pcs->http)); pcs_free(url); return PCS_NETWORK_ERROR; } if (!(*pcs->captcha_func)((unsigned char *)img, imgsz, captcha, captchaSize, pcs->captcha_data)) { pcs_set_errmsg(handle, "Can't get captch from the captcha, which is regist by user."); pcs_free(url); return PCS_GET_CAPTCHA_FAIL; } pcs_free(url); return PCS_OK; }
static inline void pcs_http_prepare(struct pcs_http *http, enum HttpMethod method, const char *url, PcsBool follow_location, PcsHttpWriteFunction write_func, void *state, curl_off_t max_recv_speed, curl_off_t max_send_speed, curl_off_t resume_from, curl_off_t max_length) { pcs_http_reset_response(http); curl_easy_setopt(http->curl, CURLOPT_USERAGENT, http->usage ? http->usage : USAGE); curl_easy_setopt(http->curl, CURLOPT_URL, url); switch(method) { case HTTP_METHOD_GET: curl_easy_setopt(http->curl, CURLOPT_HTTPGET, 1L); break; case HTTP_METHOD_POST: curl_easy_setopt(http->curl, CURLOPT_POST, 1L); break; } curl_easy_setopt(http->curl, CURLOPT_HEADER, 1L); curl_easy_setopt(http->curl, CURLOPT_CONNECTTIMEOUT, (long)http->connect_timeout); curl_easy_setopt(http->curl, CURLOPT_TIMEOUT, (long)http->timeout); curl_easy_setopt(http->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(http->curl, CURLOPT_WRITEFUNCTION, write_func); curl_easy_setopt(http->curl, CURLOPT_WRITEDATA, state); // 设置文件续传的位置给libcurl if (resume_from && max_length) { char *range = pcs_utils_sprintf("%" PRId64 "-%" PRId64, resume_from, resume_from + max_length - 1); curl_easy_setopt(http->curl, CURLOPT_RANGE, range); pcs_free(range); } else if (resume_from) { curl_easy_setopt(http->curl, CURLOPT_RESUME_FROM_LARGE, resume_from); } else { curl_easy_setopt(http->curl, CURLOPT_RESUME_FROM_LARGE, (curl_off_t)0); } curl_easy_setopt(http->curl, CURLOPT_MAX_RECV_SPEED_LARGE, max_recv_speed ? max_recv_speed : (curl_off_t)0); curl_easy_setopt(http->curl, CURLOPT_MAX_SEND_SPEED_LARGE, max_send_speed ? max_send_speed : (curl_off_t)0); if (follow_location) curl_easy_setopt(http->curl, CURLOPT_FOLLOWLOCATION, 1L); else curl_easy_setopt(http->curl, CURLOPT_FOLLOWLOCATION, 0L); if (http->progress) { curl_easy_setopt(http->curl, CURLOPT_PROGRESSFUNCTION, http->progress_func); curl_easy_setopt(http->curl, CURLOPT_PROGRESSDATA, http->progress_data); curl_easy_setopt(http->curl, CURLOPT_NOPROGRESS, (long)0); } else { curl_easy_setopt(http->curl, CURLOPT_PROGRESSFUNCTION, NULL); curl_easy_setopt(http->curl, CURLOPT_PROGRESSDATA, NULL); curl_easy_setopt(http->curl, CURLOPT_NOPROGRESS, (long)1); } }
static inline char *pcs_http_perform(struct pcs_http *http, const char *url) { CURLcode res; long httpcode; res = curl_easy_perform(http->curl); curl_easy_getinfo(http->curl, CURLINFO_RESPONSE_CODE, &httpcode); http->res_code = httpcode; if(res != CURLE_OK) { if (!http->strerror) http->strerror = pcs_utils_sprintf("%s: %s", curl_easy_strerror(res), url);//pcs_utils_strdup(curl_easy_strerror(res)); return NULL; } if (httpcode != 200 && httpcode != 206) { /*206 部分请求成功的返回码*/ if (http->strerror) pcs_free(http->strerror); http->strerror = pcs_utils_sprintf("%d %s", httpcode, http->res_body); return NULL; } if (http->response_func) (*http->response_func)((unsigned char *)http->res_body, (size_t)http->res_body_size, http->response_data); return http->res_body; }
PCS_API PcsFileInfoList *pcs_list(Pcs handle, const char *dir, int pageindex, int pagesize, const char *order, PcsBool desc) { struct pcs *pcs = (struct pcs *)handle; char *page, *pagenum, *tt; PcsFileInfoList *filist = NULL; pcs_clear_errmsg(handle); page = pcs_utils_sprintf("%d", pageindex); pagenum = pcs_utils_sprintf("%d", pagesize); tt = pcs_utils_sprintf("%d", (int)time(0)); filist = pcs_pan_api_1(handle, "list", "_", tt, "dir", dir, "page", page, "num", pagenum, "order", order, desc ? "desc" : "", desc ? "1" : "0", NULL); pcs_free(page); pcs_free(pagenum); pcs_free(tt); return filist; }
/*pcs_build_pan_api_url()的矢量模式*/ static char *pcs_build_pan_api_url_v(Pcs handle, const char *action, va_list args) { struct pcs *pcs = (struct pcs *)handle; char *baseurl, *url, *tt; tt = pcs_utils_sprintf("%d", (int)time(0)); baseurl = (char *)alloca(strlen(URL_PAN_API) + strlen(action) + 1); strcpy(baseurl, URL_PAN_API); strcat(baseurl, action); baseurl = pcs_http_build_url(pcs->http, baseurl, "channel", "chunlei", "clienttype", "0", "web","1", "t", tt, "bdstoken", pcs->bdstoken, NULL); pcs_free(tt); if (!baseurl) return NULL; url = pcs_http_build_url_v(pcs->http, baseurl, args); pcs_free(baseurl); return url; }
PCS_API PcsRes pcs_login(Pcs handle) { struct pcs *pcs = (struct pcs *)handle; PcsRes res; char *p, *html, *url, *token, *code_string, captch[8], *post_data, *tt; cJSON *json, *root, *item; int error = -1, i; pcs_clear_errmsg(handle); html = pcs_http_get(pcs->http, URL_HOME, PcsTrue); if (!html) { pcs_set_errmsg(handle, "Can't get response from the server."); return PCS_NETWORK_ERROR; } html = pcs_http_get(pcs->http, URL_PASSPORT_API "login", PcsTrue); if (!html) { pcs_set_errmsg(handle, "Can't get response from the server."); return PCS_NETWORK_ERROR; } url = pcs_utils_sprintf(URL_PASSPORT_API "getapi" "&tpl=ik" "&apiver=v3" "&class=login" "&tt=%d", (int)time(0)); html = pcs_http_get(pcs->http, url, PcsTrue); pcs_free(url); if (!html) { pcs_set_errmsg(handle, "Can't get response from the server."); return PCS_NETWORK_ERROR; } json = cJSON_Parse(html); if (!json){ pcs_set_errmsg(handle, "Can't parse the response as object. Response: %s", html); return PCS_WRONG_RESPONSE; } root = cJSON_GetObjectItem(json, "data"); if (!root) { pcs_set_errmsg(handle, "Can't read res.data. Response: %s", html); cJSON_Delete(json); return PCS_WRONG_RESPONSE; } item = cJSON_GetObjectItem(root, "token"); if (!item) { pcs_set_errmsg(handle, "Can't read res.token. Response: %s", html); cJSON_Delete(json); return PCS_WRONG_RESPONSE; } token = pcs_utils_strdup(item->valuestring); item = cJSON_GetObjectItem(root, "codeString"); if (!item) { pcs_set_errmsg(handle, "Can't read res.codeString. Response: %s", html); pcs_free(token); cJSON_Delete(json); return PCS_WRONG_RESPONSE; } code_string = pcs_utils_strdup(item->valuestring); cJSON_Delete(json); p = token; while (*p) { if (!((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))) { pcs_set_errmsg(handle, "Invalid token. Token: %s", token); pcs_free(token); pcs_free(code_string); return PCS_WRONG_RESPONSE; } p++; } i = 0; try_login: if (code_string[0]) { res = pcs_get_captcha(pcs, code_string, captch, sizeof(captch)); if (res != PCS_OK) { pcs_free(token); pcs_free(code_string); return res; } } tt = pcs_utils_sprintf("%d", (int)time(0)); post_data = pcs_http_build_post_data(pcs->http, "ppui_logintime", "6852", "charset", "UTF-8", "codestring", code_string, "token", token, "isPhone", "false", "index", "0", "u", "", "safeflg", "0", "staticpage", "http://www.baidu.com/cache/user/html/jump.html", "loginType", "1", "tpl", "mn", "callback", "parent.bdPass.api.login._postCallback", "username", pcs->username, "password", pcs->password, "verifycode", captch, "mem_pass", "on", "tt", tt, NULL); pcs_free(tt); if (!post_data) { pcs_set_errmsg(handle, "Can't build the post data."); pcs_free(token); pcs_free(code_string); return PCS_BUILD_POST_DATA; } html = pcs_http_post(pcs->http, URL_PASSPORT_API "login", post_data, PcsTrue); pcs_free(post_data); if (!html) { pcs_set_errmsg(handle, "Can't get the response from the server."); pcs_free(token); pcs_free(code_string); return PCS_NETWORK_ERROR; } else { char *errorStr = pcs_get_embed_query_int_value_by_key(html, "&error"); if (!errorStr) { pcs_set_errmsg(handle, "Can't read the error from the response. Response: %s", html); pcs_free(token); pcs_free(code_string); return PCS_NETWORK_ERROR; } error = atoi(errorStr); pcs_free(errorStr); } if (error == 0) { if (pcs_islogin(pcs) == PCS_LOGIN) { pcs_free(token); pcs_free(code_string); return PCS_OK; } else { pcs_set_errmsg(handle, "Unknown Error"); pcs_free(token); pcs_free(code_string); return PCS_FAIL; } } else { if (code_string) pcs_free(code_string); code_string = pcs_get_embed_query_token_by_key(html, "&codestring"); if (!code_string) { pcs_set_errmsg(handle, "Can't read the codestring from the response. Response: %s", html); pcs_free(token); pcs_free(code_string); return PCS_FAIL; } } if (i < 1 && code_string[0]) { i++; goto try_login; } pcs_free(token); pcs_free(code_string); pcs_set_errmsg(handle, "Unknown Error"); return PCS_FAIL; }