Subversion Repositories Kolibri OS

Rev

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