/* * Return a newlly allocated string with the next dpip token in the socket. * Return value: token string and length on success, NULL otherwise. * (useful for handling null characters in the data stream) */ char *a_Dpip_dsh_read_token2(Dsh *dsh, int blocking, int *DataSize) { char *p, *ret = NULL; *DataSize = 0; /* Read all available data without blocking */ Dpip_dsh_read(dsh, 0); /* switch mode upon request */ if (dsh->mode & DPIP_LAST_TAG) dsh->mode = DPIP_RAW; if (blocking) { if (dsh->mode & DPIP_TAG) { /* Only wait for data when the tag is incomplete */ if (!strstr(dsh->rdbuf->str, DPIP_TAG_END)) { do { Dpip_dsh_read(dsh, 1); p = strstr(dsh->rdbuf->str, DPIP_TAG_END); } while (!p && dsh->status == EAGAIN); } } else if (dsh->mode & DPIP_RAW) { /* Wait for data when the buffer is empty and there's no ERR/EOF */ while (dsh->rdbuf->len == 0 && dsh->status != DPIP_ERROR && dsh->status != DPIP_EOF) Dpip_dsh_read(dsh, 1); } } if (dsh->mode & DPIP_TAG) { /* return a full tag */ if ((p = strstr(dsh->rdbuf->str, DPIP_TAG_END))) { ret = dStrndup(dsh->rdbuf->str, p - dsh->rdbuf->str + 3); *DataSize = p - dsh->rdbuf->str + 3; dStr_erase(dsh->rdbuf, 0, p - dsh->rdbuf->str + 3); if (strstr(ret, DPIP_MODE_SWITCH_TAG)) dsh->mode |= DPIP_LAST_TAG; } } else { /* raw mode, return what we have "as is" */ if (dsh->rdbuf->len > 0) { ret = dStrndup(dsh->rdbuf->str, dsh->rdbuf->len); *DataSize = dsh->rdbuf->len; dStr_truncate(dsh->rdbuf, 0); } } return ret; }
/* * Inject full page content directly into the cache. * Used for "about:splash". May be used for "about:cache" too. */ static void Cache_entry_inject(const DilloUrl *Url, Dstr *data_ds) { CacheEntry_t *entry; if (!(entry = Cache_entry_search(Url))) entry = Cache_entry_add(Url); entry->Flags |= CA_GotData + CA_GotHeader + CA_GotLength + CA_InternalUrl; if (data_ds->len) entry->Flags &= ~CA_IsEmpty; dStr_truncate(entry->Data, 0); dStr_append_l(entry->Data, data_ds->str, data_ds->len); dStr_fit(entry->Data); entry->ExpectedSize = entry->TransferSize = entry->Data->len; }
/* * Streamed write to socket * Return: 0 on success, 1 on error. */ int a_Dpip_dsh_write(Dsh *dsh, int flush, const char *Data, int DataSize) { int ret = 1; /* append to buf */ dStr_append_l(dsh->wrbuf, Data, DataSize); if (!flush || dsh->wrbuf->len == 0) return 0; ret = Dpip_dsh_write(dsh, 0, dsh->wrbuf->str, dsh->wrbuf->len); if (ret == dsh->wrbuf->len) { dStr_truncate(dsh->wrbuf, 0); ret = 0; } return ret; }
/* * Make the http query string */ Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester, bool_t use_proxy) { char *ptr, *cookies, *referer, *auth; Dstr *query = dStr_new(""), *request_uri = dStr_new(""), *proxy_auth = dStr_new(""); if (use_proxy) { dStr_sprintfa(request_uri, "%s%s", URL_STR(url), (URL_PATH_(url) || URL_QUERY_(url)) ? "" : "/"); if ((ptr = strrchr(request_uri->str, '#'))) dStr_truncate(request_uri, ptr - request_uri->str); if (HTTP_Proxy_Auth_base64) dStr_sprintf(proxy_auth, "Proxy-Authorization: Basic %s\r\n", HTTP_Proxy_Auth_base64); } else { dStr_sprintfa(request_uri, "%s%s%s%s", URL_PATH(url), URL_QUERY_(url) ? "?" : "", URL_QUERY(url), (URL_PATH_(url) || URL_QUERY_(url)) ? "" : "/"); } cookies = a_Cookies_get_query(url, requester); auth = a_Auth_get_auth_str(url, request_uri->str); referer = Http_get_referer(url); if (URL_FLAGS(url) & URL_Post) { Dstr *content_type = Http_make_content_type(url); dStr_sprintfa( query, "POST %s HTTP/1.1\r\n" "Connection: close\r\n" "Accept: text/*,image/*,*/*;q=0.2\r\n" "Accept-Charset: utf-8,*;q=0.8\r\n" "Accept-Encoding: gzip\r\n" "%s" /* language */ "%s" /* auth */ "Host: %s\r\n" "%s" "%s" "User-Agent: %s\r\n" "Content-Length: %ld\r\n" "Content-Type: %s\r\n" "%s" /* cookies */ "\r\n", request_uri->str, HTTP_Language_hdr, auth ? auth : "", URL_AUTHORITY(url), proxy_auth->str, referer, prefs.http_user_agent, (long)URL_DATA(url)->len, content_type->str, cookies); dStr_append_l(query, URL_DATA(url)->str, URL_DATA(url)->len); dStr_free(content_type, TRUE); } else { dStr_sprintfa( query, "GET %s HTTP/1.1\r\n" "%s" "Connection: close\r\n" "Accept: text/*,image/*,*/*;q=0.2\r\n" "Accept-Charset: utf-8,*;q=0.8\r\n" "Accept-Encoding: gzip\r\n" "%s" /* language */ "%s" /* auth */ "Host: %s\r\n" "%s" "%s" "User-Agent: %s\r\n" "%s" /* cookies */ "\r\n", request_uri->str, (URL_FLAGS(url) & URL_E2EQuery) ? "Cache-Control: no-cache\r\nPragma: no-cache\r\n" : "", HTTP_Language_hdr, auth ? auth : "", URL_AUTHORITY(url), proxy_auth->str, referer, prefs.http_user_agent, cookies); } dFree(referer); dFree(cookies); dFree(auth); dStr_free(request_uri, TRUE); dStr_free(proxy_auth, TRUE); _MSG("Query: {%s}\n", dStr_printable(query, 8192)); return query; }