Subversion Repositories Kolibri OS

Rev

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