Subversion Repositories Kolibri OS

Rev

Rev 7758 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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