Subversion Repositories Kolibri OS

Rev

Rev 6969 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7281 leency 1
//===================================================//
2
//                                                   //
3
//                       HTTP                        //
4
//                                                   //
5
//===================================================//
6058 leency 6
 
7281 leency 7
struct _http
8
{
9
    dword url;
10
    dword transfer;
11
    dword content_length;
12
    dword content_received;
13
    dword status_code;
14
    dword receive_result;
15
    dword content_pointer;
16
 
17
    dword get();
18
    void free();
19
    void receive();
20
    bool handle_redirect();
21
};
22
 
23
dword _http::get(dword _url)
24
{
25
    url = _url;
26
    http_get stdcall (url, 0, 0, #accept_language);
27
    transfer = EAX;
28
    return transfer;
29
}
30
 
31
void _http::free()
32
{
33
    http_free stdcall (transfer);
34
    transfer=0;
35
}
36
 
37
void _http::receive()
38
{
39
    http_receive stdcall (transfer);
40
    receive_result = EAX;
41
 
42
    ESI = transfer;
43
    if (!EAX) status_code = ESI.http_msg.status;
44
    content_length = ESI.http_msg.content_length;
45
    content_received = ESI.http_msg.content_received;
46
 
47
 }
48
 
49
bool _http::handle_redirect()
50
{
51
	dword redirect, i;
52
	char redirect_url[4096*3], finaladress[4096*3];
53
    http_find_header_field stdcall (transfer, "location\0");
54
    if (EAX!=0) {
55
        ESI = EAX;
56
        EDI = #redirect_url;
57
        do {
58
            $lodsb;
59
            $stosb;
60
        } while (AL != 0) && (AL != 13) && (AL != 10);
61
        DSBYTE[EDI-1]='\0';
62
        get_absolute_url(#finaladress, url, #redirect_url);
63
        strcpy(url, #finaladress);
64
        return true;
65
    }
66
    return false;
67
}
68
 
69
//===================================================//
70
//                                                   //
71
//                    DOWNLOADER                     //
72
//                                                   //
73
//===================================================//
74
 
75
 
6058 leency 76
enum {
77
	STATE_NOT_STARTED,
78
	STATE_IN_PROGRESS,
79
	STATE_COMPLETED
80
};
81
 
82
struct DOWNLOADER {
7281 leency 83
	_http httpd;
6058 leency 84
	unsigned data_downloaded_size, data_full_size;
85
	dword bufpointer, bufsize, url;
7281 leency 86
	int state;
6058 leency 87
	dword Start();
88
	void Stop();
89
	void Completed();
90
	int MonitorProgress();
91
} downloader;
92
 
93
dword DOWNLOADER::Start(dword _url)
94
{
95
	url = _url;
96
	state = STATE_IN_PROGRESS;
7281 leency 97
	httpd.get(url);
98
	return httpd.transfer;
6058 leency 99
}
100
 
101
void DOWNLOADER::Stop()
102
{
103
	state = STATE_NOT_STARTED;
7281 leency 104
	if (httpd.transfer!=0)
6058 leency 105
	{
7281 leency 106
		EAX = httpd.transfer;
6058 leency 107
		EAX = EAX.http_msg.content_ptr;		// get pointer to data
108
		$push EAX							// save it on the stack
7281 leency 109
		http_free stdcall (httpd.transfer);	// abort connection
6058 leency 110
		$pop  EAX
7281 leency 111
		free(EAX);						// free data
112
		httpd.transfer=0;
6058 leency 113
		bufsize = 0;
7281 leency 114
		bufpointer = free(bufpointer);
6058 leency 115
	}
116
	data_downloaded_size = data_full_size = 0;
117
}
118
 
119
void DOWNLOADER::Completed()
120
{
121
	state = STATE_COMPLETED;
7281 leency 122
	ESI = httpd.transfer;
6058 leency 123
	bufpointer = ESI.http_msg.content_ptr;
124
	bufsize = ESI.http_msg.content_received;
7281 leency 125
	httpd.free();
6058 leency 126
}
127
 
128
int DOWNLOADER::MonitorProgress()
129
{
130
	dword receive_result;
131
	char redirect_url[4096*3], finaladress[4096*3];
7281 leency 132
	if (httpd.transfer <= 0) return false;
133
	http_receive stdcall (httpd.transfer);
6058 leency 134
	receive_result = EAX;
7281 leency 135
	EDI = httpd.transfer;
136
	httpd.status_code = EDI.http_msg.status;
6058 leency 137
	data_full_size = EDI.http_msg.content_length;
138
	data_downloaded_size = EDI.http_msg.content_received;
139
	if (!data_full_size) data_full_size = data_downloaded_size * 6 + 1;
140
 
141
	if (receive_result == 0) {
7281 leency 142
		if (httpd.status_code >= 300) && (httpd.status_code < 400)
6058 leency 143
		{
7281 leency 144
			httpd.handle_redirect();
145
			strcpy(url, httpd.url);
6058 leency 146
			get_absolute_url(#finaladress, url, #redirect_url);
147
			Stop();
148
			Start(#finaladress);
149
			url = #finaladress;
150
			return false;
151
		}
152
		Completed();
153
	}
154
	return true;
155
}
156
 
157
 
158
/*=====================================
159
==                                   ==
7281 leency 160
==         CHECK PATH TYPE           ==
6058 leency 161
==                                   ==
162
=====================================*/
163
 
164
 
165
int check_is_the_adress_local(dword _in)
166
{
167
	if (ESBYTE[_in]!='/') return false;
168
	_in++;
169
	if(!strncmp(_in,"rd/",3)) return true;
170
	if(!strncmp(_in,"fd/",3)) return true;
6216 leency 171
	if(!strncmp(_in,"hd",2)) return true;
172
	if(!strncmp(_in,"bd",2)) return true;
173
	if(!strncmp(_in,"cd",2)) return true;
6058 leency 174
	if(!strncmp(_in,"sys/",4)) return true;
175
	if(!strncmp(_in,"tmp/",4)) return true;
6216 leency 176
	if(!strncmp(_in,"usbhd",5)) return true;
6058 leency 177
	if(!strncmp(_in,"kolibrios",10)) return true;
178
	return false;
179
}
180
 
181
int check_is_the_url_absolute(dword _in)
182
{
183
	if(!strncmp(_in,"ftp:",4)) return true;
184
	if(!strncmp(_in,"http:",5)) return true;
185
	if(!strncmp(_in,"https:",6)) return true;
186
	if(!strncmp(_in,"mailto:",7)) return true;
187
	if(check_is_the_adress_local(_in)) return true;
188
	return false;
189
}
190
 
191
void get_absolute_url(dword _rez, _base, _new)
192
{
193
	int i;
194
	debug("_base:");debugln(_base);
195
	debug("_new:");debugln(_new);
196
	//case: ./valera.html
197
	if (!strncmp(_new,"./", 2)) _new+=2;
198
	//case: http://site.name
199
	if (check_is_the_url_absolute(_new)) {
200
		strcpy(_rez, _new);
201
		goto _GET_ABSOLUTE_URL_END;
202
	}
203
	//case: /valera.html
204
	if (ESBYTE[_new] == '/') //remove everything after site domain name
205
	{
206
		strcpy(_rez, _base);
207
		i = strchr(_rez+8,'/');
208
		if (i<1) i=strlen(_rez)+_rez;
209
		strcpy(i, _new);
210
		goto _GET_ABSOLUTE_URL_END;
211
	}
212
	//case: ../../valera.html
213
	strcpy(_rez, _base);
214
	ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0'; //remove name
215
	while (!strncmp(_new,"../",3))
216
	{
217
		_new += 3;
218
		ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0';
219
	}
220
	//case: valera.html
221
	chrcat(_rez, '/');
222
	strcat(_rez, _new);
223
	_GET_ABSOLUTE_URL_END:
224
	while (i=strstr(_rez, "&")) strcpy(i+1, i+5);
225
	debug("_rez:");debugln(_rez);
226
}