CFContext * curl_fetch_init(const char * uri, const char * headers, int flags) { CLOGI("curl_fetch_init enter\n"); if (!uri || strlen(uri) < 1 || strlen(uri) > MAX_CURL_URI_SIZE) { CLOGE("CFContext invalid uri path\n"); return NULL; } CFContext * handle = (CFContext *)c_malloc(sizeof(CFContext)); if (!handle) { CLOGE("CFContext invalid\n"); return NULL; } handle->cwc_h = curl_wrapper_init(flags); if (!handle->cwc_h) { CLOGE("curl_wrapper_init failed\n"); return NULL; } #if 1 if (c_stristart(uri, "http://", NULL) || c_stristart(uri, "shttp://", NULL)) { handle->prot_type = C_PROT_HTTP; } else if (c_stristart(uri, "https://", NULL) || c_stristart(uri, "shttps://", NULL)) { handle->prot_type = C_PROT_HTTPS; } memset(handle->uri, 0, sizeof(handle->uri)); if (c_stristart(uri, "shttp://", NULL) || c_stristart(uri, "shttps://", NULL)) { c_strlcpy(handle->uri, uri + 1, sizeof(handle->uri)); } else { c_strlcpy(handle->uri, uri, sizeof(handle->uri)); } curl_fetch_url_process(handle); CLOGI("curl_fetch_init, uri:[%s]\n", handle->uri); #endif handle->cwd = (Curl_Data *)c_malloc(sizeof(Curl_Data)); if (!handle->cwd) { CLOGE("Failed to allocate memory for curl_data\n"); return NULL; } handle->cwh_h = curl_wrapper_open(handle->cwc_h, handle->uri, headers, handle->cwd, handle->prot_type); if (!handle->cwh_h) { CLOGE("curl_wrapper_open failed\n"); return NULL; } handle->chunk = NULL; handle->thread_quited = 0; handle->perform_retval = 0; handle->http_code = 0; handle->filesize = -1; handle->seekable = 0; handle->relocation = NULL; handle->headers = NULL; handle->interrupt = NULL; pthread_mutex_init(&handle->quit_mutex, NULL); pthread_cond_init(&handle->quit_cond, NULL); if (headers) { handle->headers = (char *)c_mallocz(strlen(headers) + 1); strcpy(handle->headers, headers); } return handle; }
/* defined for some abnormal uri, like ip port -> :80:80 */ static int curl_fetch_url_process(CFContext * h) { if (!h) { CLOGE("CFContext invalid\n"); return -1; } char t_uri[MAX_CURL_URI_SIZE] = {0}; char ip[256] = {0}; char * fptr = c_stristr(h->uri, "//"); char * bptr = c_stristr(fptr + 2, "/"); if(fptr && bptr) { int len1 = fptr - h->uri + 2; memcpy(t_uri, h->uri, len1); memcpy(ip, h->uri + len1, (bptr - h->uri - len1) > 256 ? 256 : (bptr - h->uri - len1)); char * ip_ptr = c_stristr(ip, ":"); if(ip_ptr) { int len2 = ip_ptr - ip; memcpy(t_uri + len1, ip, len2); len1 += len2; char * ip_rptr = c_strrstr(ip, ":"); if(ip_ptr) { int len3 = strlen(ip) - (ip_rptr - ip); memcpy(t_uri + len1, ip_rptr, len3); len1 += len3; } } else { memcpy(t_uri + len1, ip, strlen(ip)); len1 += strlen(ip); } int len4 = strlen(h->uri) - (bptr - h->uri); memcpy(t_uri + len1, bptr, len4); c_strlcpy(h->uri, t_uri, sizeof(h->uri)); } return 0; }
const char * sircc_ssl_get_error(void) { char *ptr; size_t len; bool empty_queue; ptr = sircc_ssl_error_buf; len = C_ERROR_BUFSZ; empty_queue = true; for (;;) { unsigned long errcode; const char *errstr; size_t errlen; if (ptr > sircc_ssl_error_buf) { *ptr = ' '; ptr++; len--; } errcode = ERR_get_error(); if (errcode == 0) break; empty_queue = false; errstr = ERR_error_string(errcode, NULL); c_strlcpy(ptr, errstr, len); errlen = strlen(errstr); if (errlen >= len) break; ptr += errlen; len -= errlen; } if (empty_queue) c_strlcpy(ptr, "empty ssl error queue", len); return sircc_ssl_error_buf; }
/* * headers must composed of fields split with "\r\n". * This is just temporary, need to modify later */ int curl_fetch_http_set_headers(CFContext * h, const char * headers) { CLOGI("curl_fetch_http_set_headers enter\n"); if (!h) { CLOGE("CFContext invalid\n"); return -1; } char fields[2048]; char * end_ptr = headers; char * beg_ptr = headers; while (*beg_ptr != '\0') { if (!(end_ptr = strstr(beg_ptr, "\r\n"))) { break; } if (beg_ptr == end_ptr) { beg_ptr += 2; continue; } memset(fields, 0x00, sizeof(fields)); int tmp = CURLMIN(end_ptr - beg_ptr + 1, sizeof(fields) - 1); c_strlcpy(fields, beg_ptr, tmp); fields[tmp] = '\0'; /* char * tmp_ptr = c_strrstr(fields, "\r\n"); // must remove CRLF if(tmp_ptr) { *tmp_ptr = '\0'; } beg_ptr = end_ptr + 5; */ beg_ptr = end_ptr + 2; #if 0 if (c_stristart(fields, "Connection:", NULL) || c_stristart(fields, "X-Playback-Session-Id:", NULL)) { h->chunk = curl_slist_append(h->chunk, fields); CLOGI("curl_fetch_http_set_headers fields=[%s]", fields); } #else h->chunk = curl_slist_append(h->chunk, fields); CLOGI("curl_fetch_http_set_headers fields=[%s]", fields); #endif } int ret = 0; if (h->prot_type == C_PROT_HTTP) { ret = curl_wrapper_set_para(h->cwh_h, (void *)h->chunk, C_HTTPHEADER, 0, NULL); } return ret; }
int curl_fetch_http_keepalive_open(CFContext * h, const char * uri) { CLOGI("curl_fetch_http_keepalive_open enter\n"); int ret = -1; if (!h) { CLOGE("CFContext invalid\n"); return ret; } curl_wrapper_set_to_quit(h->cwc_h, NULL); if (curl_fetch_waitthreadquit(h, 5000 * 1000)) { return ret; } curl_wrapper_clean_after_perform(h->cwc_h); if (h->cwh_h->cfifo) { curl_fifo_reset(h->cwh_h->cfifo); } if (uri) { if (c_stristart(uri, "http://", NULL) || c_stristart(uri, "shttp://", NULL)) { h->prot_type = C_PROT_HTTP; } if (h->prot_type != C_PROT_HTTP) { return ret; } memset(h->uri, 0, sizeof(h->uri)); if (c_stristart(uri, "shttp://", NULL)) { c_strlcpy(h->uri, uri + 1, sizeof(h->uri)); } else { c_strlcpy(h->uri, uri, sizeof(h->uri)); } curl_fetch_url_process(h); CLOGI("curl_fetch_http_keepalive_open, uri:[%s]\n", h->uri); ret = curl_wrapper_http_keepalive_open(h->cwc_h, h->cwh_h, h->uri); } else { ret = curl_wrapper_http_keepalive_open(h->cwc_h, h->cwh_h, uri); } if (-1 == ret) { CLOGE("curl_wrapper_http_keepalive_open failed\n"); return ret; } h->thread_quited = 0; h->perform_retval = 0; h->http_code = 0; h->filesize = -1; h->seekable = 0; //h->is_seeking = 0; h->cwd->size = 0; curl_fetch_start_local_run(h); #if 0 struct timeval now; struct timespec timeout; int retcode = 0; gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec + (15000000 + now.tv_usec) / 1000000; timeout.tv_nsec = now.tv_usec * 1000; if(h->open_quited) { return -1; } pthread_mutex_lock(&h->cwh_h->info_mutex); retcode = pthread_cond_timedwait(&h->cwh_h->info_cond, &h->cwh_h->info_mutex, &timeout); if (retcode != ETIMEDOUT) { if (h->cwh_h->chunk_size > 0) { h->filesize = h->cwh_h->chunk_size; } if (h->cwh_h->relocation) { h->relocation = h->cwh_h->relocation; } h->http_code = h->cwh_h->http_code; } pthread_mutex_unlock(&h->cwh_h->info_mutex); #endif int timeout = 0; while(!h->cwh_h->open_quited && timeout < CONNECT_TIMEOUT_THRESHOLD) { if(h->interrupt) { if((*(h->interrupt))()) { CLOGE("***** CURL INTERRUPTED *****"); return -1; // consider for seek interrupt } } usleep(SLEEP_TIME_UNIT); timeout += SLEEP_TIME_UNIT; } if(h->cwh_h->perform_error_code < C_ERROR_EAGAIN) { return -1; } if(h->cwh_h->open_quited) { if (h->cwh_h->chunk_size > 0) { h->filesize = h->cwh_h->chunk_size; } if (h->cwh_h->relocation) { h->relocation = h->cwh_h->relocation; } h->http_code = h->cwh_h->http_code; } else { h->http_code = ETIMEDOUT; return -1; } if (h->http_code >= 400 && h->http_code < 600 && h->http_code != 401) { return -1; } if (h->filesize > 0 || h->cwh_h->seekable) { h->seekable = 1; } return 0; }
int sircc_highlighter_init_escape_sequences(struct sircc_highlighter *highlighter, const char *str, size_t sz) { const char *and; const char *ptr; size_t len; size_t nb_sequences; nb_sequences = sizeof(sircc_highlighting_sequences) / sizeof(sircc_highlighting_sequences[0]); ptr = str; len = sz; while (len > 0) { const char *sequence; size_t toklen; and = memchr(ptr, '&', len); if (and) { toklen = (size_t)(and - ptr); } else { toklen = len; } sequence = NULL; for (size_t i = 0; i < nb_sequences; i++) { const char *name; name = sircc_highlighting_sequences[i].name; if (toklen == strlen(name) && memcmp(ptr, name, toklen) == 0) { sequence = sircc_highlighting_sequences[i].sequence; break; } } if (!sequence) { char tmp[toklen + 1]; c_strlcpy(tmp, ptr, toklen + 1); c_set_error("unknown display attribute '%s'", tmp); return -1; } if (highlighter->sequence) { char *tmp; c_asprintf(&tmp, "%s%s", highlighter->sequence, sequence); c_free(highlighter->sequence); highlighter->sequence = tmp; } else { highlighter->sequence = strdup(sequence); } ptr += toklen; len -= toklen; if (and) { ptr++; len--; } } return 0; }