PTR_WEIBO_ENTITY show_single_weibo_byid(const char* access_token, const char* weibo_id) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "ss", access_token, weibo_id); char s[20] = {}; cJSON* root = NULL; PTR_WEIBO_ENTITY weibo = NULL; PTR_HTTP_REQUEST request = alloc_http_request(2, 0, 0, 0); PTR_HTTP_RESPONSE response = NULL; request->params[0].name = "access_token"; request->params[0].value = access_token; request->params[1].name = "id"; request->params[1].value = weibo_id; response = https_get(WEIBO_SHOW_WEIBO_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return NULL; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return NULL; } weibo = create_weibo_entity_from_json(root); free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return weibo; }
PTR_WEIBO_ENTITY show_multiple_weibo_byids(const char* access_token, char** weibo_ids, uint32_t count) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "spd", access_token, weibo_ids, count); char s[2048] = {}; uint32_t i = 0; uint32_t cnt = count>MAX_BATCH_SIZE?MAX_BATCH_SIZE:count; cJSON* root = NULL; cJSON* statuses = NULL; PTR_WEIBO_ENTITY list_head = NULL; PTR_WEIBO_ENTITY weibo = NULL; PTR_HTTP_REQUEST request = alloc_http_request(2, 0, 0, 0); PTR_HTTP_RESPONSE response = NULL; memset(s, 0, sizeof(char)*sizeof(s)); sprintf(s, "%s", weibo_ids[0]); for (i=1; i<cnt; i++) { sprintf(s, "%s,%s", s, weibo_ids[i]); } s[strlen(s)] = '\0'; request->params[0].name = "access_token"; request->params[0].value = access_token; request->params[1].name = "ids"; request->params[1].value = s; response = https_get(WEIBO_SHOW_WEIBO_BATCH_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return NULL; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return NULL; } statuses = cJSON_GetObjectItem(root, "statuses"); cnt = cJSON_GetArraySize(statuses); for (i=0; i<cnt; i++) { weibo = create_weibo_entity_from_json(cJSON_GetArrayItem(statuses, i)); weibo->next = list_head; weibo->prev = NULL; if (list_head != NULL) { list_head->prev = weibo; } list_head = weibo; } free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return list_head; }
char* fetch_access_token(const char* code, char* token) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "sp", code, token); cJSON* root = NULL; PTR_HTTP_REQUEST request = alloc_http_request(5, 0, 0, 0); PTR_HTTP_RESPONSE response = NULL; request->params[0].name = "client_id"; request->params[0].value = APP_KEY; request->params[1].name = "client_secret"; request->params[1].value = APP_SECRET; request->params[2].name = "grant_type"; request->params[2].value = "authorization_code"; request->params[3].name = "code"; request->params[3].value = code; request->params[4].name = "redirect_uri"; request->params[4].value = APP_AUTH_REDIRECT_URL; response = https_post(APP_FETCH_TOKEN_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return NULL; } root = cJSON_Parse((char*)(response->body)); sprintf(token, "%s", cJSON_GetObjectItem(root, "access_token")->valuestring); free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return token; }
BOOL get_access_token_info(const char* access_token) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "s", access_token); cJSON* root = NULL; PTR_HTTP_REQUEST request = alloc_http_request(1, 0, 0, 0); PTR_HTTP_RESPONSE response = NULL; request->params[0].name = "access_token"; request->params[0].value = access_token; response = https_post(APP_GET_TOKEN_INFO_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return False; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return False; } free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return True; }
PTR_WEIBO_ENTITY get_user_timeline(const char* access_token, const char* uid, int page) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "sd", access_token, page); char s[20] = {}; int i=0, cnt = 0; cJSON* root = NULL; cJSON* statuses = NULL; PTR_WEIBO_ENTITY list_head = NULL; PTR_WEIBO_ENTITY weibo = NULL; PTR_HTTP_REQUEST request = alloc_http_request(3, 0, 0, 0); PTR_HTTP_RESPONSE response = NULL; request->params[0].name = "access_token"; request->params[0].value = access_token; request->params[1].name = "page"; snprintf(s, 20, "%d", page); request->params[1].value = s; request->params[2].name = "uid"; request->params[2].value = uid; response = https_get(WEIBO_GET_USER_TIMELINE_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return NULL; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return NULL; } statuses = cJSON_GetObjectItem(root, "statuses"); cnt = cJSON_GetArraySize(statuses); for (i=0; i<cnt; i++) { weibo = create_weibo_entity_from_json(cJSON_GetArrayItem(statuses, i)); weibo->next = list_head; weibo->prev = NULL; if (list_head != NULL) { list_head->prev = weibo; } list_head = weibo; } free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return list_head; }
PTR_WEIBO_ENTITY get_user_timeline_byname(const char* access_token, const char* name, int page) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "ssd", access_token, name, page); char s[20] = {}; char *weibo_id = NULL; int i = 0, cnt = 0; cJSON* root = NULL; PTR_WEIBO_ENTITY list_head = NULL; PTR_WEIBO_ENTITY weibo = NULL; PTR_HTTP_REQUEST request = alloc_http_request(4, 0, 0, 0); PTR_HTTP_RESPONSE response = NULL; request->params[0].name = "access_token"; request->params[0].value = access_token; request->params[1].name = "name"; request->params[1].value = name; snprintf(s, 20, "%d", page); request->params[2].name="page"; request->params[2].value=s; request->params[3].name="count"; request->params[3].value="5"; /* hard code as 5 for api invocation limit */ response = https_get(WEIBO_GET_USER_TIMELINE_IDS_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return NULL; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return NULL; } cnt = cJSON_GetArraySize(cJSON_GetObjectItem(root, "statuses")); for (i=0; i<cnt; i++) { weibo_id = (cJSON_GetArrayItem(cJSON_GetObjectItem(root, "statuses"), i))->valuestring; weibo = show_single_weibo_byid(access_token, weibo_id); weibo->next = list_head; weibo->prev = NULL; if (list_head != NULL) { list_head->prev = weibo; } list_head = weibo; } free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return list_head; }
char* get_ip_from_url(char* url) { char* ip = NULL; http_response* page = get_url(url, NULL); if(page != NULL) { if(page->data != NULL) { int status; regex_t re; if (regcomp(&re, "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", REG_EXTENDED) == 0) { regmatch_t m[5]; status = regexec(&re, page->data, (size_t) 5, m, 0); if(status == 0) { int ip_length = m[0].rm_eo - m[0].rm_so; ip = (char*)malloc((1+ip_length)*sizeof(char)); ip = memcpy(ip, page->data + m[0].rm_so, ip_length); ip[ip_length] = '\0'; } regfree(&re); } } free_http_response(page); } return ip; }
PTR_WEIBO_ENTITY get_user_timeline_byids(const char* access_token, const char* uid, int page) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "ssd", access_token, uid, page); char s[20] = {}; char **weibo_ids = NULL; int i = 0, cnt = 0; cJSON* root = NULL; PTR_WEIBO_ENTITY list_head = NULL; PTR_WEIBO_ENTITY weibo = NULL; PTR_HTTP_REQUEST request = alloc_http_request(3, 0, 0, 0); PTR_HTTP_RESPONSE response = NULL; request->params[0].name = "access_token"; request->params[0].value = access_token; request->params[1].name = "uid"; request->params[1].value = uid; snprintf(s, 20, "%d", page); request->params[2].name="page"; request->params[2].value=s; response = https_get(WEIBO_GET_USER_TIMELINE_IDS_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return NULL; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return NULL; } cnt = cJSON_GetArraySize(cJSON_GetObjectItem(root, "statuses")); weibo_ids = (char**) malloc(sizeof(char*)*cnt); for (i=0; i<cnt; i++) { weibo_ids[i] = (cJSON_GetArrayItem(cJSON_GetObjectItem(root, "statuses"), i))->valuestring; } list_head = show_multiple_weibo_byids(access_token, weibo_ids, cnt); free_http_request(request); free_http_response(response); free(weibo_ids); cJSON_Delete(root); debug_log_exit(FINE, func_name); return list_head; }
BOOL repost_weibo(const char* access_token, const char* text, const char* weibo_id) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "sss", access_token, text, weibo_id); cJSON* root = NULL; PTR_HTTP_REQUEST request = alloc_http_request(0, 0, 0, (100+strlen(text))*sizeof(char)); PTR_HTTP_RESPONSE response = NULL; /* request->form[0].name = "access_token"; request->form[0].value = access_token; request->form[0].type = STRING; request->form[1].name = "status"; request->form[1].value = text; request->form[1].type = STRING; request->form[2].name = "id"; request->form[2].value = weibo_id; request->form[2].type = STRING; */ sprintf((char*)(request->body), "access_token=%s&id=%s&status=%s", access_token, weibo_id, text); request->body_length = strlen((char*)(request->body)); response = https_post(WEIBO_REPOST_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return False; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return False; } free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return True; }
BOOL create_weibo_pic(const char* access_token, const char* text, const char* pic_name) { const char* func_name = __func__; debug_log_enter(FINE, func_name, "ss", access_token, text); cJSON* root = NULL; PTR_HTTP_REQUEST request = alloc_http_request(0, 0, 3, 0); PTR_HTTP_RESPONSE response = NULL; request->form[0].name = "access_token"; request->form[0].value = access_token; request->form[0].type = STRING; request->form[1].name = "status"; request->form[1].value = text; request->form[1].type = STRING; request->form[2].name = "pic"; request->form[2].value = pic_name; request->form[2].type = FILENAME; response = https_post(WEIBO_CREATE_URL, request); if (response->status_code != 200) { free_http_request(request); free_http_response(response); return False; } root = cJSON_Parse((char*)(response->body)); if (check_api_error(root)) { free_http_request(request); free_http_response(response); cJSON_Delete(root); return False; } free_http_request(request); free_http_response(response); cJSON_Delete(root); debug_log_exit(FINE, func_name); return True; }
/********************************************************************* * * Function : redirect_url * * Description : Checks for redirection URLs and returns a HTTP redirect * to the destination URL, if necessary * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) * * Returns : NULL if URL was clean, HTTP redirect otherwise. * *********************************************************************/ struct http_response *redirect_url(struct client_state *csp) { char *p, *q; struct http_response *rsp; p = q = csp->http->path; log_error(LOG_LEVEL_REDIRECTS, "checking path for redirects: %s", p); /* * find the last URL encoded in the request */ while ((p = strstr(p, "http://")) != NULL) { q = p++; } /* * if there was any, generate and return a HTTP redirect */ if (q != csp->http->path) { log_error(LOG_LEVEL_REDIRECTS, "redirecting to: %s", q); if (NULL == (rsp = alloc_http_response())) { return cgi_error_memory(); } if ( enlist_unique_header(rsp->headers, "Location", q) || (NULL == (rsp->status = strdup("302 Local Redirect from Privoxy"))) ) { free_http_response(rsp); return cgi_error_memory(); } return finish_http_response(rsp); } else { return NULL; } }
/* * Parses return code from libcurl operation and * reports if different than 200 and 100 */ void check_response_code(churl_context* context) { long response_code; char *response_text = NULL; int curl_error; if (CURLE_OK != (curl_error = curl_easy_getinfo(context->curl_handle, CURLINFO_RESPONSE_CODE, &response_code))) elog(ERROR, "internal error: curl_easy_getinfo failed(%d - %s)", curl_error, curl_easy_strerror(curl_error)); elog(DEBUG2, "http response code: %ld", response_code); if ((response_code == 0) && (context->curl_still_running > 0)) { elog(DEBUG2, "check_response_code: curl is still running, but no data was received."); } else if (response_code != 200 && response_code != 100) { StringInfoData err; char *http_error_msg; char *addr; initStringInfo(&err); /* prepare response text if any */ if (context->download_buffer->ptr) { context->download_buffer->ptr[context->download_buffer->top] = '\0'; response_text = context->download_buffer->ptr + context->download_buffer->bot; } /* add remote http error code */ appendStringInfo(&err, "remote component error (%ld)", response_code); addr = get_dest_address(context->curl_handle); if (strlen(addr) != 0) { appendStringInfo(&err, " from %s", addr); } pfree(addr); if (!handle_special_error(response_code, &err)) { /* * add detailed error message from the http response. response_text * could be NULL in some cases. get_http_error_msg checks for that. */ http_error_msg = get_http_error_msg(response_code, response_text, context->curl_error_buffer); /* check for a specific confusing error, and replace with a clearer one */ if (strstr(http_error_msg, "instance does not contain any root resource classes") != NULL) { appendStringInfo(&err, " : PXF not correctly installed in CLASSPATH"); } else { appendStringInfo(&err, ": %s", http_error_msg); } } elog(ERROR, "%s", err.data); } free_http_response(context); }
/********************************************************************* * * Function : trust_url FIXME: I should be called distrust_url * * Description : Calls is_untrusted_url to determine if the URL is trusted * and if not, returns a HTTP 304 response with a reject message. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) * * Returns : NULL => trusted, else http_response. * *********************************************************************/ struct http_response *trust_url(struct client_state *csp) { struct http_response *rsp; struct map * exports; char buf[BUFFER_SIZE]; char *p; struct url_spec **tl; struct url_spec *t; jb_err err; /* * Don't bother to work on trusted URLs */ if (!is_untrusted_url(csp)) { return NULL; } /* * Else, prepare a response: */ if (NULL == (rsp = alloc_http_response())) { return cgi_error_memory(); } exports = default_exports(csp, NULL); if (exports == NULL) { free_http_response(rsp); return cgi_error_memory(); } /* * Export the protocol, host, port, and referrer information */ err = map(exports, "hostport", 1, csp->http->hostport, 1); if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); if (!err) err = map(exports, "path", 1, csp->http->path, 1); if (NULL != (p = get_header_value(csp->headers, "Referer:"))) { if (!err) err = map(exports, "referrer", 1, html_encode(p), 0); } else { if (!err) err = map(exports, "referrer", 1, "unknown", 1); } if (err) { free_map(exports); free_http_response(rsp); return cgi_error_memory(); } /* * Export the trust list */ p = strdup(""); for (tl = csp->config->trust_list; (t = *tl) != NULL ; tl++) { sprintf(buf, "<li>%s</li>\n", t->spec); string_append(&p, buf); } err = map(exports, "trusted-referrers", 1, p, 0); if (err) { free_map(exports); free_http_response(rsp); return cgi_error_memory(); } /* * Export the trust info, if available */ if (csp->config->trust_info->first) { struct list_entry *l; p = strdup(""); for (l = csp->config->trust_info->first; l ; l = l->next) { sprintf(buf, "<li> <a href=\"%s\">%s</a><br>\n",l->str, l->str); string_append(&p, buf); } err = map(exports, "trust-info", 1, p, 0); } else { err = map_block_killer(exports, "have-trust-info"); } if (err) { free_map(exports); free_http_response(rsp); return cgi_error_memory(); } /* * Export the force prefix or the force conditional block killer */ #ifdef FEATURE_FORCE_LOAD err = map(exports, "force-prefix", 1, FORCE_PREFIX, 1); #else /* ifndef FEATURE_FORCE_LOAD */ err = map_block_killer(exports, "force-support"); #endif /* ndef FEATURE_FORCE_LOAD */ if (err) { free_map(exports); free_http_response(rsp); return cgi_error_memory(); } /* * Build the response */ err = template_fill_for_cgi(csp, "untrusted", exports, rsp); if (err) { free_http_response(rsp); return cgi_error_memory(); } return finish_http_response(rsp); }
/********************************************************************* * * Function : block_url * * Description : Called from `chat'. Check to see if we need to block this. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) * * Returns : NULL => unblocked, else HTTP block response * *********************************************************************/ struct http_response *block_url(struct client_state *csp) { #ifdef FEATURE_IMAGE_BLOCKING char *p; #endif /* def FEATURE_IMAGE_BLOCKING */ struct http_response *rsp; /* * If it's not blocked, don't block it ;-) */ if ((csp->action->flags & ACTION_BLOCK) == 0) { return NULL; } /* * Else, prepare a response */ if (NULL == (rsp = alloc_http_response())) { return cgi_error_memory(); } /* * If it's an image-url, send back an image or redirect * as specified by the relevant +image action */ #ifdef FEATURE_IMAGE_BLOCKING if (((csp->action->flags & ACTION_IMAGE_BLOCKER) != 0) && is_imageurl(csp)) { /* determine HOW images should be blocked */ p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER]; #if 1 /* Two alternative strategies, use this one for now: */ /* and handle accordingly: */ if ((p == NULL) || (0 == strcmpic(p, "pattern"))) { rsp->body = bindup(image_pattern_data, image_pattern_length); if (rsp->body == NULL) { free_http_response(rsp); return cgi_error_memory(); } rsp->content_length = image_pattern_length; if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE)) { free_http_response(rsp); return cgi_error_memory(); } } else if (0 == strcmpic(p, "blank")) { rsp->body = bindup(image_blank_data, image_blank_length); if (rsp->body == NULL) { free_http_response(rsp); return cgi_error_memory(); } rsp->content_length = image_blank_length; if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE)) { free_http_response(rsp); return cgi_error_memory(); } } else { rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free_http_response(rsp); return cgi_error_memory(); } if (enlist_unique_header(rsp->headers, "Location", p)) { free_http_response(rsp); return cgi_error_memory(); } } #else /* Following code is disabled for now */ /* and handle accordingly: */ if ((p == NULL) || (0 == strcmpic(p, "pattern"))) { p = CGI_PREFIX "send-banner?type=pattern"; } else if (0 == strcmpic(p, "blank")) { p = CGI_PREFIX "send-banner?type=blank"; } rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free_http_response(rsp); return cgi_error_memory(); } if (enlist_unique_header(rsp->headers, "Location", p)) { free_http_response(rsp); return cgi_error_memory(); } #endif /* Preceeding code is disabled for now */ } else #endif /* def FEATURE_IMAGE_BLOCKING */ /* * Else, generate an HTML "blocked" message: */ { jb_err err; struct map * exports; /* * Workaround for stupid Netscape bug which prevents * pages from being displayed if loading a referenced * JavaScript or style sheet fails. So make it appear * as if it succeeded. */ if ( NULL != (p = get_header_value(csp->headers, "User-Agent:")) && !strncmpic(p, "mozilla", 7) /* Catch Netscape but */ && !strstr(p, "Gecko") /* save Mozilla, */ && !strstr(p, "compatible") /* MSIE */ && !strstr(p, "Opera")) /* and Opera. */ { rsp->status = strdup("200 Request for blocked URL"); } else { rsp->status = strdup("404 Request for blocked URL"); } if (rsp->status == NULL) { free_http_response(rsp); return cgi_error_memory(); } exports = default_exports(csp, NULL); if (exports == NULL) { free_http_response(rsp); return cgi_error_memory(); } #ifdef FEATURE_FORCE_LOAD err = map(exports, "force-prefix", 1, FORCE_PREFIX, 1); if (csp->http->ssl != 0) #endif /* ndef FEATURE_FORCE_LOAD */ { err = map_block_killer(exports, "force-support"); } if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); if (!err) err = map(exports, "hostport", 1, html_encode(csp->http->hostport), 0); if (!err) err = map(exports, "path", 1, html_encode(csp->http->path), 0); if (!err) err = map(exports, "path-ue", 1, url_encode(csp->http->path), 0); if (err) { free_map(exports); free_http_response(rsp); return cgi_error_memory(); } err = template_fill_for_cgi(csp, "blocked", exports, rsp); if (err) { free_http_response(rsp); return cgi_error_memory(); } } return finish_http_response(rsp); }