Subversion Repositories Kolibri OS

Rev

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

Rev 7293 Rev 7422
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",10)) 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(check_is_the_adress_local(_in)) return true;
177
	if(check_is_the_adress_local(_in)) return true;
178
	return false;
178
	return false;
179
}
179
}
180
 
180
 
181
void get_absolute_url(dword _rez, _base, _new)
181
void get_absolute_url(dword _rez, _base, _new)
182
{
182
{
183
	int i;
183
	int i;
184
	//case: ./valera.html
184
	//case: ./valera.html
185
	if (!strncmp(_new,"./", 2)) _new+=2;
185
	if (!strncmp(_new,"./", 2)) _new+=2;
186
	//case: http://site.name
186
	//case: http://site.name
187
	if (check_is_the_url_absolute(_new)) {
187
	if (check_is_the_url_absolute(_new)) {
188
		strcpy(_rez, _new);
188
		strcpy(_rez, _new);
189
		goto _GET_ABSOLUTE_URL_END;
189
		goto _GET_ABSOLUTE_URL_END;
190
	}
190
	}
191
	//case: /valera.html
191
	//case: /valera.html
192
	if (ESBYTE[_new] == '/') //remove everything after site domain name
192
	if (ESBYTE[_new] == '/') //remove everything after site domain name
193
	{
193
	{
194
		strcpy(_rez, _base);
194
		strcpy(_rez, _base);
195
		i = strchr(_rez+8,'/');
195
		i = strchr(_rez+8,'/');
196
		if (i<1) i=strlen(_rez)+_rez;
196
		if (i<1) i=strlen(_rez)+_rez;
197
		strcpy(i, _new);
197
		strcpy(i, _new);
198
		goto _GET_ABSOLUTE_URL_END;
198
		goto _GET_ABSOLUTE_URL_END;
199
	}	
199
	}	
200
	//case: ../../valera.html
200
	//case: ../../valera.html
201
	strcpy(_rez, _base);
201
	strcpy(_rez, _base);
202
	ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0'; //remove name
202
	ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0'; //remove name
203
	while (!strncmp(_new,"../",3))
203
	while (!strncmp(_new,"../",3))
204
	{
204
	{
205
		_new += 3;
205
		_new += 3;
206
		ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0';	
206
		ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0';	
207
	}
207
	}
208
	//case: valera.html
208
	//case: valera.html
209
	chrcat(_rez, '/');
209
	chrcat(_rez, '/');
210
	strcat(_rez, _new); 
210
	strcat(_rez, _new); 
211
	_GET_ABSOLUTE_URL_END:
211
	_GET_ABSOLUTE_URL_END:
212
	while (i=strstr(_rez, "&")) strcpy(i+1, i+5);	
212
	while (i=strstr(_rez, "&")) strcpy(i+1, i+5);	
213
}
213
}