mpg123-1.31.0
This commit is contained in:
@@ -5,13 +5,11 @@
|
||||
#include <ws2tcpip.h>
|
||||
#include <wininet.h>
|
||||
|
||||
const char *net123_backends[] = { "(always wininet)", NULL };
|
||||
|
||||
// The network implementation defines the struct for private use.
|
||||
// The purpose is just to keep enough context to be able to
|
||||
// call net123_read() and net123_close() afterwards.
|
||||
#define URL_COMPONENTS_LENGTH 255
|
||||
struct net123_handle_struct {
|
||||
typedef struct {
|
||||
HINTERNET session;
|
||||
HINTERNET connect;
|
||||
HINTERNET request;
|
||||
@@ -28,7 +26,7 @@ struct net123_handle_struct {
|
||||
DWORD HttpQueryInfoIndex;
|
||||
DWORD internetStatus, internetStatusLength;
|
||||
LPVOID additionalInfo;
|
||||
};
|
||||
} wininet_handle;
|
||||
|
||||
#define MPG123CONCAT_(x,y) x ## y
|
||||
#define MPG123CONCAT(x,y) MPG123CONCAT_(x,y)
|
||||
@@ -60,13 +58,17 @@ static void debug_crack(URL_COMPONENTSW *comps){}
|
||||
|
||||
static
|
||||
void WINAPI net123_ssl_errors(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength){
|
||||
net123_handle *nh = (net123_handle *)dwContext;
|
||||
debug("In net123_ssl_errors");
|
||||
wininet_handle *nh = (wininet_handle *)(dwContext);
|
||||
nh->internetStatus = dwInternetStatus;
|
||||
nh->additionalInfo = lpvStatusInformation;
|
||||
nh->internetStatusLength = dwStatusInformationLength;
|
||||
}
|
||||
|
||||
net123_handle *net123_open(const char *url, const char * const *client_head){
|
||||
static size_t net123_read(net123_handle *nh, void *buf, size_t bufsize);
|
||||
static void net123_close(net123_handle *nh);
|
||||
|
||||
net123_handle *net123_open_wininet(const char *url, const char * const *client_head){
|
||||
LPWSTR urlW = NULL, headers = NULL;
|
||||
size_t ii;
|
||||
WINBOOL res;
|
||||
@@ -78,51 +80,63 @@ net123_handle *net123_open(const char *url, const char * const *client_head){
|
||||
if(urlW == NULL) goto cleanup;
|
||||
|
||||
net123_handle *ret = calloc(1, sizeof(net123_handle));
|
||||
if (!ret) return ret;
|
||||
wininet_handle *wh = calloc(1, sizeof(wininet_handle));
|
||||
if(!ret || !wh)
|
||||
{
|
||||
if(ret)
|
||||
free(ret);
|
||||
if(wh)
|
||||
free(wh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->comps.dwStructSize = sizeof(ret->comps);
|
||||
ret->comps.dwSchemeLength = URL_COMPONENTS_LENGTH - 1;
|
||||
ret->comps.dwUserNameLength = URL_COMPONENTS_LENGTH - 1;
|
||||
ret->comps.dwPasswordLength = URL_COMPONENTS_LENGTH - 1;
|
||||
ret->comps.dwHostNameLength = URL_COMPONENTS_LENGTH - 1;
|
||||
ret->comps.dwUrlPathLength = URL_COMPONENTS_LENGTH - 1;
|
||||
ret->comps.dwExtraInfoLength = URL_COMPONENTS_LENGTH - 1;
|
||||
ret->comps.lpszHostName = ret->lpszHostName;
|
||||
ret->comps.lpszUserName = ret->lpszUserName;
|
||||
ret->comps.lpszPassword = ret->lpszPassword;
|
||||
ret->comps.lpszUrlPath = ret->lpszUrlPath;
|
||||
ret->comps.lpszExtraInfo = ret->lpszExtraInfo;
|
||||
ret->comps.lpszScheme = ret->lpszScheme;
|
||||
ret->parts = wh;
|
||||
ret->read = net123_read;
|
||||
ret->close = net123_close;
|
||||
|
||||
wh->comps.dwStructSize = sizeof(wh->comps);
|
||||
wh->comps.dwSchemeLength = URL_COMPONENTS_LENGTH - 1;
|
||||
wh->comps.dwUserNameLength = URL_COMPONENTS_LENGTH - 1;
|
||||
wh->comps.dwPasswordLength = URL_COMPONENTS_LENGTH - 1;
|
||||
wh->comps.dwHostNameLength = URL_COMPONENTS_LENGTH - 1;
|
||||
wh->comps.dwUrlPathLength = URL_COMPONENTS_LENGTH - 1;
|
||||
wh->comps.dwExtraInfoLength = URL_COMPONENTS_LENGTH - 1;
|
||||
wh->comps.lpszHostName = wh->lpszHostName;
|
||||
wh->comps.lpszUserName = wh->lpszUserName;
|
||||
wh->comps.lpszPassword = wh->lpszPassword;
|
||||
wh->comps.lpszUrlPath = wh->lpszUrlPath;
|
||||
wh->comps.lpszExtraInfo = wh->lpszExtraInfo;
|
||||
wh->comps.lpszScheme = wh->lpszScheme;
|
||||
|
||||
debug1("net123_open start crack %S", urlW);
|
||||
|
||||
if(!(res = InternetCrackUrlW(urlW, 0, 0, &ret->comps))) {
|
||||
if(!(res = InternetCrackUrlW(urlW, 0, 0, &wh->comps))) {
|
||||
debug1("net123_open crack fail %lu", GetLastError());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
debug("net123_open crack OK");
|
||||
debug_crack(&ret->comps);
|
||||
debug_crack(&wh->comps);
|
||||
|
||||
ret->session = InternetOpenW(useragent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
wh->session = InternetOpenW(useragent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
free(urlW);
|
||||
urlW = NULL;
|
||||
debug("net123_open InternetOpenW OK");
|
||||
if(!ret->session) goto cleanup;
|
||||
if(!wh->session) goto cleanup;
|
||||
|
||||
debug2("net123_open InternetConnectW %S %u", ret->comps.lpszHostName, ret->comps.nPort);
|
||||
ret->connect = InternetConnectW(ret->session, ret->comps.lpszHostName, ret->comps.nPort,
|
||||
ret->comps.dwUserNameLength ? ret->comps.lpszUserName : NULL, ret->comps.dwPasswordLength ? ret->comps.lpszPassword : NULL,
|
||||
debug2("net123_open InternetConnectW %S %u", wh->comps.lpszHostName, wh->comps.nPort);
|
||||
wh->connect = InternetConnectW(wh->session, wh->comps.lpszHostName, wh->comps.nPort,
|
||||
wh->comps.dwUserNameLength ? wh->comps.lpszUserName : NULL, wh->comps.dwPasswordLength ? wh->comps.lpszPassword : NULL,
|
||||
INTERNET_SERVICE_HTTP, 0, 0);
|
||||
if(!ret->connect) goto cleanup;
|
||||
if(!wh->connect) goto cleanup;
|
||||
debug("net123_open InternetConnectW OK");
|
||||
|
||||
debug1("HttpOpenRequestW GET %S", ret->comps.lpszUrlPath);
|
||||
ret->request = HttpOpenRequestW(ret->connect, L"GET", ret->comps.lpszUrlPath, NULL, NULL, NULL, ret->comps.nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)ret);
|
||||
if(!ret->request) goto cleanup;
|
||||
debug1("HttpOpenRequestW GET %S", wh->comps.lpszUrlPath);
|
||||
wh->request = HttpOpenRequestW(wh->connect, L"GET", wh->comps.lpszUrlPath, NULL, NULL, NULL, wh->comps.nScheme == INTERNET_SCHEME_HTTPS ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)wh);
|
||||
if(!wh->request) goto cleanup;
|
||||
debug("HttpOpenRequestW GET OK");
|
||||
|
||||
cb = InternetSetStatusCallback(ret->request, (INTERNET_STATUS_CALLBACK)net123_ssl_errors);
|
||||
cb = InternetSetStatusCallback(wh->request, (INTERNET_STATUS_CALLBACK)net123_ssl_errors);
|
||||
if(cb != NULL){
|
||||
error1("InternetSetStatusCallback failed to install callback, errors might not be reported properly! (%lu)", GetLastError());
|
||||
}
|
||||
@@ -132,7 +146,7 @@ net123_handle *net123_open(const char *url, const char * const *client_head){
|
||||
if(!headers)
|
||||
goto cleanup;
|
||||
debug1("HttpAddRequestHeadersW add %S", headers);
|
||||
res = HttpAddRequestHeadersW(ret->request, headers, (DWORD) -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
|
||||
res = HttpAddRequestHeadersW(wh->request, headers, (DWORD) -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
|
||||
debug2("HttpAddRequestHeadersW returns %u %lu", res, res ? 0 : GetLastError());
|
||||
free(headers);
|
||||
headers = NULL;
|
||||
@@ -140,13 +154,14 @@ net123_handle *net123_open(const char *url, const char * const *client_head){
|
||||
|
||||
debug("net123_open ADD HEADERS OK");
|
||||
|
||||
res = HttpSendRequestW(ret->request, NULL, 0, NULL, 0);
|
||||
res = HttpSendRequestW(wh->request, NULL, 0, NULL, 0);
|
||||
|
||||
if (!res) {
|
||||
res = GetLastError();
|
||||
error1("HttpSendRequestW failed with %lu", res);
|
||||
goto cleanup;
|
||||
}
|
||||
debug("HttpSendRequestW OK");
|
||||
|
||||
// dummy, cannot be null
|
||||
headers = calloc(1,1);
|
||||
@@ -155,18 +170,20 @@ net123_handle *net123_open(const char *url, const char * const *client_head){
|
||||
error("Cannot allocate dummy buffer for HttpQueryInfoW");
|
||||
goto cleanup;
|
||||
}
|
||||
res = HttpQueryInfoW(ret->request, HTTP_QUERY_RAW_HEADERS_CRLF, headers, &headerlen, &ret->HttpQueryInfoIndex);
|
||||
debug("Try HttpQueryInfoW pass 1");
|
||||
res = HttpQueryInfoW(wh->request, HTTP_QUERY_RAW_HEADERS_CRLF, headers, &headerlen, &wh->HttpQueryInfoIndex);
|
||||
free(headers);
|
||||
debug("HttpQueryInfoW pass 1 OK");
|
||||
|
||||
if(!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER && headerlen > 0) {
|
||||
/* buffer size is in bytes, not including terminator */
|
||||
headers = calloc(1, headerlen + sizeof(*headers));
|
||||
if (!headers) goto cleanup;
|
||||
res = HttpQueryInfoW(ret->request, HTTP_QUERY_RAW_HEADERS_CRLF, headers, &headerlen, &ret->HttpQueryInfoIndex);
|
||||
res = HttpQueryInfoW(wh->request, HTTP_QUERY_RAW_HEADERS_CRLF, headers, &headerlen, &wh->HttpQueryInfoIndex);
|
||||
debug3("HttpQueryInfoW returned %u, err %u : %S", res, GetLastError(), headers ? headers : L"null");
|
||||
win32_wide_utf7(headers, &ret->headers, &ret->headers_len);
|
||||
win32_wide_utf7(headers, &wh->headers, &wh->headers_len);
|
||||
/* bytes written, skip the terminating null, we want to stop at the \r\n\r\n */
|
||||
ret->headers_len --;
|
||||
wh->headers_len --;
|
||||
free(headers);
|
||||
headers = NULL;
|
||||
} else {
|
||||
@@ -184,21 +201,24 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t net123_read(net123_handle *nh, void *buf, size_t bufsize){
|
||||
static size_t net123_read(net123_handle *nh, void *buf, size_t bufsize){
|
||||
if(!nh || !nh->parts)
|
||||
return 0;
|
||||
wininet_handle *wh = nh->parts;
|
||||
size_t ret;
|
||||
size_t to_copy = nh->headers_len - nh->headers_pos;
|
||||
size_t to_copy = wh->headers_len - wh->headers_pos;
|
||||
DWORD bytesread = 0;
|
||||
|
||||
if(to_copy){
|
||||
ret = to_copy <= bufsize ? to_copy : bufsize;
|
||||
memcpy(buf, nh->headers + nh->headers_pos, ret);
|
||||
nh->headers_pos += ret;
|
||||
memcpy(buf, wh->headers + wh->headers_pos, ret);
|
||||
wh->headers_pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* is this needed? */
|
||||
to_copy = bufsize > ULONG_MAX ? ULONG_MAX : bufsize;
|
||||
if(!InternetReadFile(nh->request, buf, to_copy, &bytesread)){
|
||||
if(!InternetReadFile(wh->request, buf, to_copy, &bytesread)){
|
||||
error1("InternetReadFile exited with %d", GetLastError());
|
||||
return EOF;
|
||||
}
|
||||
@@ -206,22 +226,28 @@ size_t net123_read(net123_handle *nh, void *buf, size_t bufsize){
|
||||
}
|
||||
|
||||
// Call that to free up resources, end processes.
|
||||
void net123_close(net123_handle *nh){
|
||||
if(nh->headers) {
|
||||
free(nh->headers);
|
||||
nh->headers = NULL;
|
||||
static void net123_close(net123_handle *nh){
|
||||
if(!nh)
|
||||
return;
|
||||
wininet_handle *wh = nh->parts;
|
||||
if(!wh) /*???*/
|
||||
return;
|
||||
if(wh->headers) {
|
||||
free(wh->headers);
|
||||
wh->headers = NULL;
|
||||
}
|
||||
if(nh->request) {
|
||||
InternetCloseHandle(nh->request);
|
||||
nh->request = NULL;
|
||||
if(wh->request) {
|
||||
InternetCloseHandle(wh->request);
|
||||
wh->request = NULL;
|
||||
}
|
||||
if(nh->connect) {
|
||||
InternetCloseHandle(nh->connect);
|
||||
nh->connect = NULL;
|
||||
if(wh->connect) {
|
||||
InternetCloseHandle(wh->connect);
|
||||
wh->connect = NULL;
|
||||
}
|
||||
if(nh->session) {
|
||||
InternetCloseHandle(nh->session);
|
||||
nh->session = NULL;
|
||||
if(wh->session) {
|
||||
InternetCloseHandle(wh->session);
|
||||
wh->session = NULL;
|
||||
}
|
||||
free(nh);
|
||||
free(wh);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user