Subversion Repositories Kolibri OS

Rev

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

Rev 4829 Rev 4830
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  HTTP library for KolibriOS                                     ;;
6
;;  HTTP library for KolibriOS                                     ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;   Written by hidnplayr@kolibrios.org                            ;;
8
;;   Written by hidnplayr@kolibrios.org                            ;;
9
;;   Proxy code written by CleverMouse                             ;;
9
;;   Proxy code written by CleverMouse                             ;;
10
;;                                                                 ;;
10
;;                                                                 ;;
11
;;         GNU GENERAL PUBLIC LICENSE                              ;;
11
;;         GNU GENERAL PUBLIC LICENSE                              ;;
12
;;          Version 2, June 1991                                   ;;
12
;;          Version 2, June 1991                                   ;;
13
;;                                                                 ;;
13
;;                                                                 ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
15
 
16
; references:
16
; references:
17
; "HTTP made really easy", http://www.jmarshall.com/easy/http/
17
; "HTTP made really easy", http://www.jmarshall.com/easy/http/
18
; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616
18
; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616
19
 
19
 
20
 
20
 
21
        URLMAXLEN       = 65535
21
        URLMAXLEN       = 65535
22
        BUFFERSIZE      = 8192
22
        BUFFERSIZE      = 8192
23
        TIMEOUT         = 500  ; in 1/100 s
23
        TIMEOUT         = 500  ; in 1/100 s
24
 
24
 
25
        __DEBUG__       = 1
25
        __DEBUG__       = 1
26
        __DEBUG_LEVEL__ = 1
26
        __DEBUG_LEVEL__ = 1
27
 
27
 
28
 
28
 
29
format MS COFF
29
format MS COFF
30
 
30
 
31
public @EXPORT as 'EXPORTS'
31
public @EXPORT as 'EXPORTS'
32
 
32
 
33
include '../../../struct.inc'
33
include '../../../struct.inc'
34
include '../../../proc32.inc'
34
include '../../../proc32.inc'
35
include '../../../macros.inc'
35
include '../../../macros.inc'
36
purge section,mov,add,sub
36
purge section,mov,add,sub
37
include '../../../debug-fdo.inc'
37
include '../../../debug-fdo.inc'
38
 
38
 
39
include '../../../network.inc'
39
include '../../../network.inc'
40
include 'http.inc'
40
include 'http.inc'
41
 
41
 
42
virtual at 0
42
virtual at 0
43
        http_msg http_msg
43
        http_msg http_msg
44
end virtual
44
end virtual
45
 
45
 
46
macro copy_till_zero {
46
macro copy_till_zero {
47
local   .copyloop, .copydone
47
local   .copyloop, .copydone
48
  .copyloop:
48
  .copyloop:
49
        lodsb
49
        lodsb
50
        test    al, al
50
        test    al, al
51
        jz      .copydone
51
        jz      .copydone
52
        stosb
52
        stosb
53
        jmp     .copyloop
53
        jmp     .copyloop
54
  .copydone:
54
  .copydone:
55
}
55
}
56
 
56
 
57
macro HTTP_init_buffer buffer, socketnum {
57
macro HTTP_init_buffer buffer, socketnum {
58
 
58
 
59
        mov     eax, buffer
59
        mov     eax, buffer
60
        push    socketnum
60
        push    socketnum
61
        popd    [eax + http_msg.socket]
61
        popd    [eax + http_msg.socket]
62
        lea     esi, [eax + http_msg.http_header]
62
        lea     esi, [eax + http_msg.http_header]
63
        mov     [eax + http_msg.flags], FLAG_CONNECTED
63
        mov     [eax + http_msg.flags], FLAG_CONNECTED
64
        mov     [eax + http_msg.write_ptr], esi
64
        mov     [eax + http_msg.write_ptr], esi
65
        mov     [eax + http_msg.buffer_length], BUFFERSIZE -  http_msg.http_header
65
        mov     [eax + http_msg.buffer_length], BUFFERSIZE -  http_msg.http_header
66
        mov     [eax + http_msg.chunk_ptr], 0
66
        mov     [eax + http_msg.chunk_ptr], 0
67
 
67
 
68
        mov     [eax + http_msg.status], 0
68
        mov     [eax + http_msg.status], 0
69
        mov     [eax + http_msg.header_length], 0
69
        mov     [eax + http_msg.header_length], 0
70
        mov     [eax + http_msg.content_ptr], 0
70
        mov     [eax + http_msg.content_ptr], 0
71
        mov     [eax + http_msg.content_length], 0
71
        mov     [eax + http_msg.content_length], 0
72
        mov     [eax + http_msg.content_received], 0
72
        mov     [eax + http_msg.content_received], 0
73
 
73
 
74
        push    eax ebp
74
        push    eax ebp
75
        mov     ebp, eax
75
        mov     ebp, eax
76
        mcall   26, 9
76
        mcall   26, 9
77
        mov     [ebp + http_msg.timestamp], eax
77
        mov     [ebp + http_msg.timestamp], eax
78
        pop     ebp eax
78
        pop     ebp eax
79
}
79
}
80
 
80
 
81
section '.flat' code readable align 16
81
section '.flat' code readable align 16
82
 
82
 
83
;;===========================================================================;;
83
;;===========================================================================;;
84
lib_init: ;//////////////////////////////////////////////////////////////////;;
84
lib_init: ;//////////////////////////////////////////////////////////////////;;
85
;;---------------------------------------------------------------------------;;
85
;;---------------------------------------------------------------------------;;
86
;? Library entry point (called after library load)                           ;;
86
;? Library entry point (called after library load)                           ;;
87
;;---------------------------------------------------------------------------;;
87
;;---------------------------------------------------------------------------;;
88
;> eax = pointer to memory allocation routine                                ;;
88
;> eax = pointer to memory allocation routine                                ;;
89
;> ebx = pointer to memory freeing routine                                   ;;
89
;> ebx = pointer to memory freeing routine                                   ;;
90
;> ecx = pointer to memory reallocation routine                              ;;
90
;> ecx = pointer to memory reallocation routine                              ;;
91
;> edx = pointer to library loading routine                                  ;;
91
;> edx = pointer to library loading routine                                  ;;
92
;;---------------------------------------------------------------------------;;
92
;;---------------------------------------------------------------------------;;
93
;< eax = 1 (fail) / 0 (ok)                                                   ;;
93
;< eax = 1 (fail) / 0 (ok)                                                   ;;
94
;;===========================================================================;;
94
;;===========================================================================;;
95
        mov     [mem.alloc], eax
95
        mov     [mem.alloc], eax
96
        mov     [mem.free], ebx
96
        mov     [mem.free], ebx
97
        mov     [mem.realloc], ecx
97
        mov     [mem.realloc], ecx
98
        mov     [dll.load], edx
98
        mov     [dll.load], edx
99
 
99
 
100
        invoke  dll.load, @IMPORT
100
        invoke  dll.load, @IMPORT
101
        test    eax, eax
101
        test    eax, eax
102
        jnz     .error
102
        jnz     .error
103
 
103
 
104
; load proxy settings
104
; load proxy settings
105
        pusha
105
        pusha
106
        invoke  ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr
106
        invoke  ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr
107
        invoke  ini.get_int, inifile, sec_proxy, key_proxyport, 80
107
        invoke  ini.get_int, inifile, sec_proxy, key_proxyport, 80
108
        mov     [proxyPort], eax
108
        mov     [proxyPort], eax
109
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
109
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
110
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
110
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
111
        popa
111
        popa
112
 
112
 
113
        DEBUGF  1, "HTTP library: init OK\n"
113
        DEBUGF  1, "HTTP library: init OK\n"
114
        xor     eax, eax
114
        xor     eax, eax
115
        ret
115
        ret
116
 
116
 
117
  .error:
117
  .error:
118
        DEBUGF  1, "ERROR loading libraries\n"
118
        DEBUGF  1, "ERROR loading libraries\n"
119
        xor     eax, eax
119
        xor     eax, eax
120
        inc     eax
120
        inc     eax
121
        ret
121
        ret
122
 
122
 
123
 
123
 
124
 
124
 
125
 
125
 
126
;;================================================================================================;;
126
;;================================================================================================;;
127
proc HTTP_get URL, add_header ;///////////////////////////////////////////////////////////////////;;
127
proc HTTP_get URL, add_header ;///////////////////////////////////////////////////////////////////;;
128
;;------------------------------------------------------------------------------------------------;;
128
;;------------------------------------------------------------------------------------------------;;
129
;? Initiates a HTTP connection, using 'GET' method.                                               ;;
129
;? Initiates a HTTP connection, using 'GET' method.                                               ;;
130
;;------------------------------------------------------------------------------------------------;;
130
;;------------------------------------------------------------------------------------------------;;
131
;> URL          = pointer to ASCIIZ URL                                                           ;;
131
;> URL          = pointer to ASCIIZ URL                                                           ;;
132
;> add_header   = pointer to additional header parameters (ASCIIZ), or null for none.             ;;
132
;> add_header   = pointer to additional header parameters (ASCIIZ), or null for none.             ;;
133
;;------------------------------------------------------------------------------------------------;;
133
;;------------------------------------------------------------------------------------------------;;
134
;< eax = 0 (error) / buffer ptr                                                                   ;;
134
;< eax = 0 (error) / buffer ptr                                                                   ;;
135
;;================================================================================================;;
135
;;================================================================================================;;
136
locals
136
locals
137
        hostname        dd ?
137
        hostname        dd ?
138
        pageaddr        dd ?
138
        pageaddr        dd ?
139
        sockaddr        dd ?
139
        sockaddr        dd ?
140
        socketnum       dd ?
140
        socketnum       dd ?
141
        buffer          dd ?
141
        buffer          dd ?
142
        port            dd ?
142
        port            dd ?
143
endl
143
endl
144
 
144
 
145
        pusha
145
        pusha
146
 
146
 
147
; split the URL into hostname and pageaddr
147
; split the URL into hostname and pageaddr
148
        stdcall parse_url, [URL]
148
        stdcall parse_url, [URL]
149
        test    eax, eax
149
        test    eax, eax
150
        jz      .error
150
        jz      .error
151
        mov     [hostname], eax
151
        mov     [hostname], eax
152
        mov     [pageaddr], ebx
152
        mov     [pageaddr], ebx
153
        mov     [port], ecx
153
        mov     [port], ecx
154
 
154
 
155
; Connect to the other side.
155
; Connect to the other side.
156
        stdcall open_connection, [hostname], [port]
156
        stdcall open_connection, [hostname], [port]
157
        test    eax, eax
157
        test    eax, eax
158
        jz      .error
158
        jz      .error
159
        mov     [socketnum], eax
159
        mov     [socketnum], eax
160
 
160
 
161
; Create the HTTP request.
161
; Create the HTTP request.
162
        invoke  mem.alloc, BUFFERSIZE
162
        invoke  mem.alloc, BUFFERSIZE
163
        test    eax, eax
163
        test    eax, eax
164
        jz      .error
164
        jz      .error
165
        mov     [buffer], eax
165
        mov     [buffer], eax
166
        mov     edi, eax
166
        mov     edi, eax
167
        DEBUGF  1, "Buffer allocated: 0x%x\n", eax
167
        DEBUGF  1, "Buffer allocated: 0x%x\n", eax
168
 
168
 
169
        mov     esi, str_get
169
        mov     esi, str_get
170
        copy_till_zero
170
        copy_till_zero
171
 
171
 
172
; If we are using a proxy, send complete URL, otherwise send only page address.
172
; If we are using a proxy, send complete URL, otherwise send only page address.
173
        cmp     [proxyAddr], 0
173
        cmp     [proxyAddr], 0
174
        je      .no_proxy
174
        je      .no_proxy
175
        mov     esi, str_http           ; prepend 'http://'
175
        mov     esi, str_http           ; prepend 'http://'
176
        copy_till_zero
176
        copy_till_zero
177
        mov     esi, [hostname]
177
        mov     esi, [hostname]
178
        copy_till_zero
178
        copy_till_zero
179
  .no_proxy:
179
  .no_proxy:
180
        mov     esi, [pageaddr]
180
        mov     esi, [pageaddr]
181
        copy_till_zero
181
        copy_till_zero
182
 
182
 
183
        mov     esi, str_http11
183
        mov     esi, str_http11
184
        mov     ecx, str_http11.length
184
        mov     ecx, str_http11.length
185
        rep     movsb
185
        rep     movsb
186
 
186
 
187
        mov     esi, [hostname]
187
        mov     esi, [hostname]
188
        copy_till_zero
188
        copy_till_zero
189
 
189
 
190
        cmp     byte[proxyUser], 0
190
        cmp     byte[proxyUser], 0
191
        je      @f
191
        je      @f
192
        call    append_proxy_auth_header
192
        call    append_proxy_auth_header
193
  @@:
193
  @@:
194
 
194
 
195
        mov     ax, 0x0a0d
195
        mov     ax, 0x0a0d
196
        stosw
196
        stosw
197
 
197
 
198
        mov     esi, [add_header]
198
        mov     esi, [add_header]
199
        test    esi, esi
199
        test    esi, esi
200
        jz      @f
200
        jz      @f
201
        copy_till_zero
201
        copy_till_zero
202
  @@:
202
  @@:
203
 
203
 
204
        mov     esi, str_close
204
        mov     esi, str_close
205
        mov     ecx, str_close.length
205
        mov     ecx, str_close.length
206
        rep     movsb
206
        rep     movsb
207
 
207
 
208
        mov     byte[edi], 0
208
        mov     byte[edi], 0
209
        DEBUGF  1, "Request:\n%s", [buffer]
209
        DEBUGF  1, "Request:\n%s", [buffer]
210
 
210
 
211
; Free unused memory
211
; Free unused memory
212
        push    edi
212
        push    edi
213
        invoke  mem.free, [pageaddr]
213
        invoke  mem.free, [pageaddr]
214
        invoke  mem.free, [hostname]
214
        invoke  mem.free, [hostname]
215
        pop     esi
215
        pop     esi
216
 
216
 
217
; Send the request
217
; Send the request
218
        sub     esi, [buffer]   ; length
218
        sub     esi, [buffer]   ; length
219
        xor     edi, edi        ; flags
219
        xor     edi, edi        ; flags
220
        mcall   send, [socketnum], [buffer]
220
        mcall   send, [socketnum], [buffer]
221
        test    eax, eax
221
        test    eax, eax
222
        jz      .error
222
        jz      .error
223
        DEBUGF  1, "Request has been sent to server.\n"
223
        DEBUGF  1, "Request has been sent to server.\n"
224
 
224
 
225
        HTTP_init_buffer [buffer], [socketnum]
225
        HTTP_init_buffer [buffer], [socketnum]
226
 
226
 
227
        popa
227
        popa
228
        mov     eax, [buffer]   ; return buffer ptr
228
        mov     eax, [buffer]   ; return buffer ptr
229
        ret
229
        ret
230
 
230
 
231
  .error:
231
  .error:
232
        DEBUGF  1, "Error!\n"
232
        DEBUGF  1, "Error!\n"
233
        popa
233
        popa
234
        xor     eax, eax        ; return 0 = error
234
        xor     eax, eax        ; return 0 = error
235
        ret
235
        ret
236
 
236
 
237
endp
237
endp
238
 
238
 
239
 
239
 
240
 
240
 
241
;;================================================================================================;;
241
;;================================================================================================;;
242
proc HTTP_head URL, add_header ;//////////////////////////////////////////////////////////////////;;
242
proc HTTP_head URL, add_header ;//////////////////////////////////////////////////////////////////;;
243
;;------------------------------------------------------------------------------------------------;;
243
;;------------------------------------------------------------------------------------------------;;
244
;? Initiates a HTTP connection, using 'HEAD' method.                                              ;;
244
;? Initiates a HTTP connection, using 'HEAD' method.                                              ;;
245
;? This will only return HTTP header and status, no content                                       ;;
245
;? This will only return HTTP header and status, no content                                       ;;
246
;;------------------------------------------------------------------------------------------------;;
246
;;------------------------------------------------------------------------------------------------;;
247
;> URL          = pointer to ASCIIZ URL                                                           ;;
247
;> URL          = pointer to ASCIIZ URL                                                           ;;
248
;> add_header   = pointer to additional header parameters (ASCIIZ), or null for none.             ;;
248
;> add_header   = pointer to additional header parameters (ASCIIZ), or null for none.             ;;
249
;;------------------------------------------------------------------------------------------------;;
249
;;------------------------------------------------------------------------------------------------;;
250
;< eax = 0 (error) / buffer ptr                                                                   ;;
250
;< eax = 0 (error) / buffer ptr                                                                   ;;
251
;;================================================================================================;;
251
;;================================================================================================;;
252
locals
252
locals
253
        hostname        dd ?
253
        hostname        dd ?
254
        pageaddr        dd ?
254
        pageaddr        dd ?
255
        sockaddr        dd ?
255
        sockaddr        dd ?
256
        socketnum       dd ?
256
        socketnum       dd ?
257
        buffer          dd ?
257
        buffer          dd ?
258
        port            dd ?
258
        port            dd ?
259
endl
259
endl
260
 
260
 
261
        pusha
261
        pusha
262
; split the URL into hostname and pageaddr
262
; split the URL into hostname and pageaddr
263
        stdcall parse_url, [URL]
263
        stdcall parse_url, [URL]
264
        test    eax, eax
264
        test    eax, eax
265
        jz      .error
265
        jz      .error
266
        mov     [hostname], eax
266
        mov     [hostname], eax
267
        mov     [pageaddr], ebx
267
        mov     [pageaddr], ebx
268
        mov     [port], ecx
268
        mov     [port], ecx
269
 
269
 
270
; Connect to the other side.
270
; Connect to the other side.
271
        stdcall open_connection, [hostname], [port]
271
        stdcall open_connection, [hostname], [port]
272
        test    eax, eax
272
        test    eax, eax
273
        jz      .error
273
        jz      .error
274
        mov     [socketnum], eax
274
        mov     [socketnum], eax
275
 
275
 
276
; Create the HTTP request.
276
; Create the HTTP request.
277
        invoke  mem.alloc, BUFFERSIZE
277
        invoke  mem.alloc, BUFFERSIZE
278
        test    eax, eax
278
        test    eax, eax
279
        jz      .error
279
        jz      .error
280
        mov     [buffer], eax
280
        mov     [buffer], eax
281
        mov     edi, eax
281
        mov     edi, eax
282
        DEBUGF  1, "Buffer has been allocated.\n"
282
        DEBUGF  1, "Buffer has been allocated.\n"
283
 
283
 
284
        mov     esi, str_head
284
        mov     esi, str_head
285
        copy_till_zero
285
        copy_till_zero
286
 
286
 
287
; If we are using a proxy, send complete URL, otherwise send only page address.
287
; If we are using a proxy, send complete URL, otherwise send only page address.
288
        cmp     [proxyAddr], 0
288
        cmp     [proxyAddr], 0
289
        je      .no_proxy
289
        je      .no_proxy
290
        mov     esi, str_http           ; prepend 'http://'
290
        mov     esi, str_http           ; prepend 'http://'
291
        copy_till_zero
291
        copy_till_zero
292
        mov     esi, [hostname]
292
        mov     esi, [hostname]
293
        copy_till_zero
293
        copy_till_zero
294
  .no_proxy:
294
  .no_proxy:
295
        mov     esi, [pageaddr]
295
        mov     esi, [pageaddr]
296
        copy_till_zero
296
        copy_till_zero
297
 
297
 
298
        mov     esi, str_http11
298
        mov     esi, str_http11
299
        mov     ecx, str_http11.length
299
        mov     ecx, str_http11.length
300
        rep     movsb
300
        rep     movsb
301
 
301
 
302
        mov     esi, [hostname]
302
        mov     esi, [hostname]
303
        copy_till_zero
303
        copy_till_zero
304
 
304
 
305
        cmp     byte[proxyUser], 0
305
        cmp     byte[proxyUser], 0
306
        je      @f
306
        je      @f
307
        call    append_proxy_auth_header
307
        call    append_proxy_auth_header
308
  @@:
308
  @@:
309
 
309
 
310
        mov     ax, 0x0a0d
310
        mov     ax, 0x0a0d
311
        stosw
311
        stosw
312
 
312
 
313
        mov     esi, [add_header]
313
        mov     esi, [add_header]
314
        test    esi, esi
314
        test    esi, esi
315
        jz      @f
315
        jz      @f
316
        copy_till_zero
316
        copy_till_zero
317
  @@:
317
  @@:
318
 
318
 
319
        mov     esi, str_close
319
        mov     esi, str_close
320
        mov     ecx, str_close.length
320
        mov     ecx, str_close.length
321
        rep     movsb
321
        rep     movsb
322
 
322
 
323
        mov     byte[edi], 0
323
        mov     byte[edi], 0
324
        DEBUGF  1, "Request:\n%s", [buffer]
324
        DEBUGF  1, "Request:\n%s", [buffer]
325
 
325
 
326
 
326
 
327
; Free unused memory
327
; Free unused memory
328
        push    edi
328
        push    edi
329
        invoke  mem.free, [pageaddr]
329
        invoke  mem.free, [pageaddr]
330
        invoke  mem.free, [hostname]
330
        invoke  mem.free, [hostname]
331
        pop     esi
331
        pop     esi
332
 
332
 
333
; Send the request
333
; Send the request
334
        sub     esi, [buffer]   ; length
334
        sub     esi, [buffer]   ; length
335
        xor     edi, edi        ; flags
335
        xor     edi, edi        ; flags
336
        mcall   send, [socketnum], [buffer]
336
        mcall   send, [socketnum], [buffer]
337
        test    eax, eax
337
        test    eax, eax
338
        jz      .error
338
        jz      .error
339
        DEBUGF  1, "Request has been sent to server.\n"
339
        DEBUGF  1, "Request has been sent to server.\n"
340
 
340
 
341
        HTTP_init_buffer [buffer], [socketnum]
341
        HTTP_init_buffer [buffer], [socketnum]
342
 
342
 
343
        popa
343
        popa
344
        mov     eax, [buffer]
344
        mov     eax, [buffer]
345
        ret                     ; return buffer ptr
345
        ret                     ; return buffer ptr
346
 
346
 
347
  .error:
347
  .error:
348
        DEBUGF  1, "Error!\n"
348
        DEBUGF  1, "Error!\n"
349
        popa
349
        popa
350
        xor     eax, eax        ; return 0 = error
350
        xor     eax, eax        ; return 0 = error
351
        ret
351
        ret
352
 
352
 
353
endp
353
endp
354
 
354
 
355
 
355
 
356
;;================================================================================================;;
356
;;================================================================================================;;
357
proc HTTP_post URL, add_header, content_type, content_length ;////////////////////////////////////;;
357
proc HTTP_post URL, add_header, content_type, content_length ;////////////////////////////////////;;
358
;;------------------------------------------------------------------------------------------------;;
358
;;------------------------------------------------------------------------------------------------;;
359
;? Initiates a HTTP connection, using 'POST' method.                                              ;;
359
;? Initiates a HTTP connection, using 'POST' method.                                              ;;
360
;? This method is used to send data to the HTTP server                                            ;;
360
;? This method is used to send data to the HTTP server                                            ;;
361
;;------------------------------------------------------------------------------------------------;;
361
;;------------------------------------------------------------------------------------------------;;
362
;> URL                  = pointer to ASCIIZ URL                                                   ;;
362
;> URL                  = pointer to ASCIIZ URL                                                   ;;
363
;> add_header           = pointer to additional header parameters (ASCIIZ), or null for none.     ;;
363
;> add_header           = pointer to additional header parameters (ASCIIZ), or null for none.     ;;
364
;> content_type         = pointer to ASCIIZ string containing content type                        ;;
364
;> content_type         = pointer to ASCIIZ string containing content type                        ;;
365
;> content_length       = length of content (in bytes)                                            ;;
365
;> content_length       = length of content (in bytes)                                            ;;
366
;;------------------------------------------------------------------------------------------------;;
366
;;------------------------------------------------------------------------------------------------;;
367
;< eax = 0 (error) / buffer ptr                                                                   ;;
367
;< eax = 0 (error) / buffer ptr                                                                   ;;
368
;;================================================================================================;;
368
;;================================================================================================;;
369
locals
369
locals
370
        hostname        dd ?
370
        hostname        dd ?
371
        pageaddr        dd ?
371
        pageaddr        dd ?
372
        sockaddr        dd ?
372
        sockaddr        dd ?
373
        socketnum       dd ?
373
        socketnum       dd ?
374
        buffer          dd ?
374
        buffer          dd ?
375
        port            dd ?
375
        port            dd ?
376
endl
376
endl
377
 
377
 
378
        pusha
378
        pusha
379
; split the URL into hostname and pageaddr
379
; split the URL into hostname and pageaddr
380
        stdcall parse_url, [URL]
380
        stdcall parse_url, [URL]
381
        test    eax, eax
381
        test    eax, eax
382
        jz      .error
382
        jz      .error
383
        mov     [hostname], eax
383
        mov     [hostname], eax
384
        mov     [pageaddr], ebx
384
        mov     [pageaddr], ebx
385
        mov     [port], ecx
385
        mov     [port], ecx
386
 
386
 
387
; Connect to the other side.
387
; Connect to the other side.
388
        stdcall open_connection, [hostname], [port]
388
        stdcall open_connection, [hostname], [port]
389
        test    eax, eax
389
        test    eax, eax
390
        jz      .error
390
        jz      .error
391
        mov     [socketnum], eax
391
        mov     [socketnum], eax
392
 
392
 
393
; Create the HTTP request.
393
; Create the HTTP request.
394
        invoke  mem.alloc, BUFFERSIZE
394
        invoke  mem.alloc, BUFFERSIZE
395
        test    eax, eax
395
        test    eax, eax
396
        jz      .error
396
        jz      .error
397
        mov     [buffer], eax
397
        mov     [buffer], eax
398
        mov     edi, eax
398
        mov     edi, eax
399
        DEBUGF  1, "Buffer has been allocated.\n"
399
        DEBUGF  1, "Buffer has been allocated.\n"
400
 
400
 
401
        mov     esi, str_post
401
        mov     esi, str_post
402
        copy_till_zero
402
        copy_till_zero
403
 
403
 
404
; If we are using a proxy, send complete URL, otherwise send only page address.
404
; If we are using a proxy, send complete URL, otherwise send only page address.
405
        cmp     [proxyAddr], 0
405
        cmp     [proxyAddr], 0
406
        je      .no_proxy
406
        je      .no_proxy
407
        mov     esi, str_http           ; prepend 'http://'
407
        mov     esi, str_http           ; prepend 'http://'
408
        copy_till_zero
408
        copy_till_zero
409
        mov     esi, [hostname]
409
        mov     esi, [hostname]
410
        copy_till_zero
410
        copy_till_zero
411
  .no_proxy:
411
  .no_proxy:
412
        mov     esi, [pageaddr]
412
        mov     esi, [pageaddr]
413
        copy_till_zero
413
        copy_till_zero
414
 
414
 
415
        mov     esi, str_http11
415
        mov     esi, str_http11
416
        mov     ecx, str_http11.length
416
        mov     ecx, str_http11.length
417
        rep     movsb
417
        rep     movsb
418
 
418
 
419
        mov     esi, [hostname]
419
        mov     esi, [hostname]
420
        copy_till_zero
420
        copy_till_zero
421
 
421
 
422
        mov     esi, str_post_cl
422
        mov     esi, str_post_cl
423
        mov     ecx, str_post_cl.length
423
        mov     ecx, str_post_cl.length
424
        rep     movsb
424
        rep     movsb
425
 
425
 
426
        mov     eax, [content_length]
426
        mov     eax, [content_length]
427
        call    eax_ascii_dec
427
        call    eax_ascii_dec
428
 
428
 
429
        mov     esi, str_post_ct
429
        mov     esi, str_post_ct
430
        mov     ecx, str_post_ct.length
430
        mov     ecx, str_post_ct.length
431
        rep     movsb
431
        rep     movsb
432
 
432
 
433
        mov     esi, [content_type]
433
        mov     esi, [content_type]
434
        copy_till_zero
434
        copy_till_zero
435
 
435
 
436
        cmp     byte[proxyUser], 0
436
        cmp     byte[proxyUser], 0
437
        je      @f
437
        je      @f
438
        call    append_proxy_auth_header
438
        call    append_proxy_auth_header
439
  @@:
439
  @@:
440
 
440
 
441
        mov     ax, 0x0a0d
441
        mov     ax, 0x0a0d
442
        stosw
442
        stosw
443
 
443
 
444
        mov     esi, [add_header]
444
        mov     esi, [add_header]
445
        test    esi, esi
445
        test    esi, esi
446
        jz      @f
446
        jz      @f
447
        copy_till_zero
447
        copy_till_zero
448
  @@:
448
  @@:
449
 
449
 
450
        mov     esi, str_close
450
        mov     esi, str_close
451
        mov     ecx, str_close.length
451
        mov     ecx, str_close.length
452
        rep     movsb
452
        rep     movsb
453
 
453
 
454
        mov     byte[edi], 0
454
        mov     byte[edi], 0
455
        DEBUGF  1, "Request:\n%s", [buffer]
455
        DEBUGF  1, "Request:\n%s", [buffer]
456
 
456
 
457
; Free unused memory
457
; Free unused memory
458
        push    edi
458
        push    edi
459
        invoke  mem.free, [pageaddr]
459
        invoke  mem.free, [pageaddr]
460
        invoke  mem.free, [hostname]
460
        invoke  mem.free, [hostname]
461
        pop     esi
461
        pop     esi
462
 
462
 
463
; Send the request
463
; Send the request
464
        sub     esi, [buffer]   ; length
464
        sub     esi, [buffer]   ; length
465
        xor     edi, edi        ; flags
465
        xor     edi, edi        ; flags
466
        mcall   send, [socketnum], [buffer]
466
        mcall   send, [socketnum], [buffer]
467
        test    eax, eax
467
        test    eax, eax
468
        jz      .error
468
        jz      .error
469
        DEBUGF  1, "Request has been sent to server.\n"
469
        DEBUGF  1, "Request has been sent to server.\n"
470
 
470
 
471
        HTTP_init_buffer [buffer], [socketnum]
471
        HTTP_init_buffer [buffer], [socketnum]
472
 
472
 
473
        popa
473
        popa
474
        mov     eax, [buffer]
474
        mov     eax, [buffer]
475
        ret                     ; return buffer ptr
475
        ret                     ; return buffer ptr
476
 
476
 
477
  .error:
477
  .error:
478
        DEBUGF  1, "Error!\n"
478
        DEBUGF  1, "Error!\n"
479
        popa
479
        popa
480
        xor     eax, eax        ; return 0 = error
480
        xor     eax, eax        ; return 0 = error
481
        ret
481
        ret
482
 
482
 
483
endp
483
endp
484
 
484
 
485
 
485
 
486
 
486
 
487
;;================================================================================================;;
487
;;================================================================================================;;
488
proc HTTP_process identifier ;////////////////////////////////////////////////////////////////////;;
488
proc HTTP_process identifier ;////////////////////////////////////////////////////////////////////;;
489
;;------------------------------------------------------------------------------------------------;;
489
;;------------------------------------------------------------------------------------------------;;
490
;? Receive data from the server, parse headers and put data in receive buffer.                    ;;
490
;? Receive data from the server, parse headers and put data in receive buffer.                    ;;
491
;? To complete a transfer, this procedure must be called over and over again untill it returns 0. ;;
491
;? To complete a transfer, this procedure must be called over and over again untill it returns 0. ;;
492
;;------------------------------------------------------------------------------------------------;;
492
;;------------------------------------------------------------------------------------------------;;
493
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
493
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
494
;;------------------------------------------------------------------------------------------------;;
494
;;------------------------------------------------------------------------------------------------;;
495
;< eax = -1 (not finished) / 0 finished                                                           ;;
495
;< eax = -1 (not finished) / 0 finished                                                           ;;
496
;;================================================================================================;;
496
;;================================================================================================;;
497
 
497
 
498
        pusha
498
        pusha
499
        mov     ebp, [identifier]
499
        mov     ebp, [identifier]
500
 
500
 
501
; If the connection is closed, return immediately
501
; If the connection is closed, return immediately
502
        test    [ebp + http_msg.flags], FLAG_CONNECTED
502
        test    [ebp + http_msg.flags], FLAG_CONNECTED
503
        jz      .connection_closed
503
        jz      .connection_closed
504
 
504
 
505
; Receive some data
505
; Receive some data
506
        mcall   recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
506
        mcall   recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
507
                      [ebp + http_msg.buffer_length], MSG_DONTWAIT
507
                      [ebp + http_msg.buffer_length], MSG_DONTWAIT
508
        cmp     eax, 0xffffffff
508
        cmp     eax, 0xffffffff
509
        je      .check_socket
509
        je      .check_socket
510
 
510
 
511
        test    eax, eax
511
        test    eax, eax
512
        jz      .server_closed
512
        jz      .server_closed
513
        DEBUGF  1, "Received %u bytes\n", eax
513
        DEBUGF  1, "Received %u bytes\n", eax
514
 
514
 
515
; Update timestamp
515
; Update timestamp
516
        push    eax
516
        push    eax
517
        mcall   26, 9
517
        mcall   26, 9
518
        mov     [ebp + http_msg.timestamp], eax
518
        mov     [ebp + http_msg.timestamp], eax
519
        pop     eax
519
        pop     eax
520
 
520
 
521
; Update pointers
521
; Update pointers
522
        mov     edi, [ebp + http_msg.write_ptr]
522
        mov     edi, [ebp + http_msg.write_ptr]
523
        add     [ebp + http_msg.write_ptr], eax
523
        add     [ebp + http_msg.write_ptr], eax
524
        sub     [ebp + http_msg.buffer_length], eax
524
        sub     [ebp + http_msg.buffer_length], eax
525
 
525
 
526
; If data is chunked, combine chunks into contiguous data.
526
; If data is chunked, combine chunks into contiguous data.
527
        test    [ebp + http_msg.flags], FLAG_CHUNKED
527
        test    [ebp + http_msg.flags], FLAG_CHUNKED
528
        jnz     .chunk_loop
528
        jnz     .chunk_loop
529
 
529
 
530
; Did we detect the (final) header yet?
530
; Did we detect the (final) header yet?
531
        test    [ebp + http_msg.flags], FLAG_GOT_HEADER
531
        test    [ebp + http_msg.flags], FLAG_GOT_HEADER
532
        jnz     .header_parsed
532
        jnz     .header_parsed
533
 
533
 
534
;--------------------------------------------------------------
534
;--------------------------------------------------------------
535
;
535
;
536
; Header parsing code begins here
536
; Header parsing code begins here
537
;
537
;
538
 
538
 
539
; We havent found the (final) header yet, search for it..
539
; We havent found the (final) header yet, search for it..
540
  .scan_again:
540
  .scan_again:
541
        ; eax = total number of bytes received so far
541
        ; eax = total number of bytes received so far
542
        mov     eax, [ebp + http_msg.write_ptr]
542
        mov     eax, [ebp + http_msg.write_ptr]
543
        sub     eax, http_msg.http_header
543
        sub     eax, http_msg.http_header
544
        sub     eax, ebp
544
        sub     eax, ebp
545
        sub     eax, [ebp + http_msg.header_length]
545
        sub     eax, [ebp + http_msg.header_length]
546
        ; edi is ptr to begin of header
546
        ; edi is ptr to begin of header
547
        lea     edi, [ebp + http_msg.http_header]
547
        lea     edi, [ebp + http_msg.http_header]
548
        add     edi, [ebp + http_msg.header_length]
548
        add     edi, [ebp + http_msg.header_length]
549
        ; put it in esi for next proc too
549
        ; put it in esi for next proc too
550
        mov     esi, edi
550
        mov     esi, edi
551
        sub     eax, 3
551
        sub     eax, 3
552
        jle     .need_more_data_for_header
552
        jle     .need_more_data_for_header
553
  .scan_loop:
553
  .scan_loop:
554
        ; scan for end of header (empty line)
554
        ; scan for end of header (empty line)
555
        cmp     dword[edi], 0x0a0d0a0d                  ; end of header
555
        cmp     dword[edi], 0x0a0d0a0d                  ; end of header
556
        je      .end_of_header
556
        je      .end_of_header
557
        cmp     word[edi+2], 0x0a0a                     ; notice the use of offset + 2, to calculate header length correctly :)
557
        cmp     word[edi+2], 0x0a0a                     ; notice the use of offset + 2, to calculate header length correctly :)
558
        je      .end_of_header
558
        je      .end_of_header
559
        inc     edi
559
        inc     edi
560
        dec     eax
560
        dec     eax
561
        jnz     .scan_loop
561
        jnz     .scan_loop
562
        jmp     .need_more_data_for_header
562
        jmp     .need_more_data_for_header
563
 
563
 
564
  .end_of_header:
564
  .end_of_header:
565
        add     edi, 4 - http_msg.http_header
565
        add     edi, 4 - http_msg.http_header
566
        sub     edi, ebp
566
        sub     edi, ebp
567
        mov     [ebp + http_msg.header_length], edi     ; If this isnt the final header, we'll use this as an offset to find real header.
567
        mov     [ebp + http_msg.header_length], edi     ; If this isnt the final header, we'll use this as an offset to find real header.
568
        DEBUGF  1, "Header length: %u\n", edi
568
        DEBUGF  1, "Header length: %u\n", edi
569
 
569
 
570
; Ok, we have found the header
570
; Ok, we have found the header
571
        cmp     dword[esi], 'HTTP'
571
        cmp     dword[esi], 'HTTP'
572
        jne     .err_header
572
        jne     .err_header
573
        cmp     dword[esi+4], '/1.0'
573
        cmp     dword[esi+4], '/1.0'
574
        je      .http_1.0
574
        je      .http_1.0
575
        cmp     dword[esi+4], '/1.1'
575
        cmp     dword[esi+4], '/1.1'
576
        jne     .err_header
576
        jne     .err_header
577
        or      [ebp + http_msg.flags], FLAG_HTTP11
577
        or      [ebp + http_msg.flags], FLAG_HTTP11
578
  .http_1.0:
578
  .http_1.0:
579
        cmp     byte[esi+8], ' '
579
        cmp     byte[esi+8], ' '
580
        jne     .err_header
580
        jne     .err_header
581
 
581
 
582
        add     esi, 9
582
        add     esi, 9
583
        xor     eax, eax
583
        xor     eax, eax
584
        xor     ebx, ebx
584
        xor     ebx, ebx
585
        mov     ecx, 3
585
        mov     ecx, 3
586
  .statusloop:
586
  .statusloop:
587
        lodsb
587
        lodsb
588
        sub     al, '0'
588
        sub     al, '0'
589
        jb      .err_header
589
        jb      .err_header
590
        cmp     al, 9
590
        cmp     al, 9
591
        ja      .err_header
591
        ja      .err_header
592
        lea     ebx, [ebx + 4*ebx]
592
        lea     ebx, [ebx + 4*ebx]
593
        shl     ebx, 1
593
        shl     ebx, 1
594
        add     ebx, eax
594
        add     ebx, eax
595
        dec     ecx
595
        dec     ecx
596
        jnz     .statusloop
596
        jnz     .statusloop
597
 
597
 
598
; Ignore "100 - Continue" lines
598
; Ignore "100 - Continue" lines
599
        cmp     ebx, 100
599
        cmp     ebx, 100
600
        je      .scan_again
600
        je      .scan_again
601
 
601
 
602
        DEBUGF  1, "Status: %u\n", ebx
602
        DEBUGF  1, "Status: %u\n", ebx
603
        mov     [ebp + http_msg.status], ebx
603
        mov     [ebp + http_msg.status], ebx
604
        or      [ebp + http_msg.flags], FLAG_GOT_HEADER
604
        or      [ebp + http_msg.flags], FLAG_GOT_HEADER
605
 
605
 
606
; Now, convert all header names to lowercase.
606
; Now, convert all header names to lowercase.
607
; This way, it will be much easier to find certain header fields, later on.
607
; This way, it will be much easier to find certain header fields, later on.
608
        lea     esi, [ebp + http_msg.http_header]
608
        lea     esi, [ebp + http_msg.http_header]
609
        mov     ecx, [ebp + http_msg.header_length]
609
        mov     ecx, [ebp + http_msg.header_length]
610
  .need_newline:
610
  .need_newline:
611
        inc     esi
611
        inc     esi
612
        dec     ecx
612
        dec     ecx
613
        jz      .convert_done
613
        jz      .convert_done
614
        cmp     byte[esi], 10
614
        cmp     byte[esi], 10
615
        jne     .need_newline
615
        jne     .need_newline
616
; We have found a newline
616
; We have found a newline
617
; A line beginning with space or tabs has no header fields.
617
; A line beginning with space or tabs has no header fields.
618
        inc     esi
618
        inc     esi
619
        dec     ecx
619
        dec     ecx
620
        jz      .convert_done
620
        jz      .convert_done
621
        cmp     byte[esi], ' '
621
        cmp     byte[esi], ' '
622
        je      .need_newline
622
        je      .need_newline
623
        cmp     byte[esi], 9    ; horizontal tab
623
        cmp     byte[esi], 9    ; horizontal tab
624
        je      .need_newline
624
        je      .need_newline
625
        jmp     .convert_loop
625
        jmp     .convert_loop
626
  .next_char:
626
  .next_char:
627
        inc     esi
627
        inc     esi
628
        dec     ecx
628
        dec     ecx
629
        jz      .convert_done
629
        jz      .convert_done
630
  .convert_loop:
630
  .convert_loop:
631
        cmp     byte[esi], ':'
631
        cmp     byte[esi], ':'
632
        je      .need_newline
632
        je      .need_newline
633
        cmp     byte[esi], 'A'
633
        cmp     byte[esi], 'A'
634
        jb      .next_char
634
        jb      .next_char
635
        cmp     byte[esi], 'Z'
635
        cmp     byte[esi], 'Z'
636
        ja      .next_char
636
        ja      .next_char
637
        or      byte[esi], 0x20 ; convert to lowercase
637
        or      byte[esi], 0x20 ; convert to lowercase
638
        jmp     .next_char
638
        jmp     .next_char
639
  .convert_done:
639
  .convert_done:
640
        mov     byte[esi-1], 0
640
        mov     byte[esi-1], 0
641
        lea     esi, [ebp + http_msg.http_header]
641
        lea     esi, [ebp + http_msg.http_header]
642
        DEBUGF  1, "Header names converted to lowercase:\n%s\n", esi
642
        DEBUGF  1, "Header names converted to lowercase:\n%s\n", esi
643
 
643
 
644
; Check for content-length header field.
644
; Check for content-length header field.
645
        stdcall HTTP_find_header_field, ebp, str_cl
645
        stdcall HTTP_find_header_field, ebp, str_cl
646
        test    eax, eax
646
        test    eax, eax
647
        jz      .no_content
647
        jz      .no_content
648
        or      [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
648
        or      [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
649
 
649
 
650
        xor     edx, edx
650
        xor     edx, edx
651
  .cl_loop:
651
  .cl_loop:
652
        movzx   ebx, byte[eax]
652
        movzx   ebx, byte[eax]
653
        inc     eax
653
        inc     eax
654
        cmp     bl, 10
654
        cmp     bl, 10
655
        je      .cl_ok
655
        je      .cl_ok
656
        cmp     bl, 13
656
        cmp     bl, 13
657
        je      .cl_ok
657
        je      .cl_ok
658
        cmp     bl, ' '
658
        cmp     bl, ' '
659
        je      .cl_ok
659
        je      .cl_ok
660
        sub     bl, '0'
660
        sub     bl, '0'
661
        jb      .err_header
661
        jb      .err_header
662
        cmp     bl, 9
662
        cmp     bl, 9
663
        ja      .err_header
663
        ja      .err_header
664
        lea     edx, [edx + edx*4]      ; edx = edx*10
664
        lea     edx, [edx + edx*4]      ; edx = edx*10
665
        shl     edx, 1                  ;
665
        shl     edx, 1                  ;
666
        add     edx, ebx
666
        add     edx, ebx
667
        jmp     .cl_loop
667
        jmp     .cl_loop
668
 
668
 
669
  .cl_ok:
669
  .cl_ok:
670
        mov     [ebp + http_msg.content_length], edx
670
        mov     [ebp + http_msg.content_length], edx
671
        DEBUGF  1, "Content-length: %u\n", edx
671
        DEBUGF  1, "Content-length: %u\n", edx
672
 
672
 
673
        test    edx, edx
673
        test    edx, edx
674
        jz      .got_all_data
674
        jz      .got_all_data
675
 
675
 
676
        call    alloc_contentbuff
676
        call    alloc_contentbuff
677
        test    eax, eax
677
        test    eax, eax
678
        jz      .err_no_ram
678
        jz      .err_no_ram
679
        xor     eax, eax
679
        xor     eax, eax
680
        jmp     .header_parsed
680
        jmp     .header_parsed
681
 
681
 
682
  .no_content:
682
  .no_content:
683
        DEBUGF  1, "Content-length not found.\n"
683
        DEBUGF  1, "Content-length not found.\n"
684
 
684
 
685
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
685
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
686
; Try to find 'transfer-encoding' header.
686
; Try to find 'transfer-encoding' header.
687
        stdcall HTTP_find_header_field, ebp, str_te
687
        stdcall HTTP_find_header_field, ebp, str_te
688
        test    eax, eax
688
        test    eax, eax
689
        jnz     .ct_hdr_found
689
        jnz     .ct_hdr_found
690
 
690
 
691
  .not_chunked:
691
  .not_chunked:
692
        mov     edx, BUFFERSIZE
692
        mov     edx, BUFFERSIZE
693
        call    alloc_contentbuff
693
        call    alloc_contentbuff
694
        test    eax, eax
694
        test    eax, eax
695
        jz      .err_no_ram
695
        jz      .err_no_ram
696
        xor     eax, eax
696
        xor     eax, eax
697
        jmp     .header_parsed
697
        jmp     .header_parsed
698
 
698
 
699
  .ct_hdr_found:
699
  .ct_hdr_found:
700
        mov     ebx, dword[eax]
700
        mov     ebx, dword[eax]
701
        or      ebx, 0x20202020
701
        or      ebx, 0x20202020
702
        cmp     ebx, 'chun'
702
        cmp     ebx, 'chun'
703
        jne     .not_chunked
703
        jne     .not_chunked
704
        mov     ebx, dword[eax+4]
704
        mov     ebx, dword[eax+4]
705
        or      ebx, 0x00202020
705
        or      ebx, 0x00202020
706
        and     ebx, 0x00ffffff
706
        and     ebx, 0x00ffffff
707
        cmp     ebx, 'ked'
707
        cmp     ebx, 'ked'
708
        jne     .not_chunked
708
        jne     .not_chunked
709
 
709
 
710
        or      [ebp + http_msg.flags], FLAG_CHUNKED
710
        or      [ebp + http_msg.flags], FLAG_CHUNKED
711
        DEBUGF  1, "Transfer type is: chunked\n"
711
        DEBUGF  1, "Transfer type is: chunked\n"
712
 
712
 
713
        mov     edx, BUFFERSIZE
713
        mov     edx, BUFFERSIZE
714
        call    alloc_contentbuff
714
        call    alloc_contentbuff
715
        test    eax, eax
715
        test    eax, eax
716
        jz      .err_no_ram
716
        jz      .err_no_ram
717
 
717
 
718
; Set chunk pointer where first chunk should begin.
718
; Set chunk pointer where first chunk should begin.
719
        mov     eax, [ebp + http_msg.content_ptr]
719
        mov     eax, [ebp + http_msg.content_ptr]
720
        mov     [ebp + http_msg.chunk_ptr], eax
720
        mov     [ebp + http_msg.chunk_ptr], eax
721
 
721
 
722
;--------------------------------------------------------------
722
;--------------------------------------------------------------
723
;
723
;
724
; Chunk parsing code begins here
724
; Chunk parsing code begins here
725
;
725
;
726
 
726
 
727
  .chunk_loop:
727
  .chunk_loop:
728
        mov     ecx, [ebp + http_msg.write_ptr]
728
        mov     ecx, [ebp + http_msg.write_ptr]
729
        sub     ecx, [ebp + http_msg.chunk_ptr]
729
        sub     ecx, [ebp + http_msg.chunk_ptr]
730
        jbe     .need_more_data_chunked
730
        jbe     .need_more_data_chunked
731
 
731
 
732
; Chunkline starts here, convert the ASCII hex number into ebx
732
; Chunkline starts here, convert the ASCII hex number into ebx
733
        mov     esi, [ebp + http_msg.chunk_ptr]
733
        mov     esi, [ebp + http_msg.chunk_ptr]
734
        DEBUGF  1, "Chunkline begins at 0x%x\n", esi
734
        DEBUGF  1, "Chunkline begins at 0x%x\n", esi
735
 
735
 
736
        xor     ebx, ebx
736
        xor     ebx, ebx
737
        cmp     byte[esi], 0x0d
737
        cmp     byte[esi], 0x0d
738
        jne     .chunk_hex_loop
738
        jne     .chunk_hex_loop
739
        dec     ecx
739
        dec     ecx
740
        jz      .need_more_data_chunked
740
        jz      .need_more_data_chunked
741
        inc     esi
741
        inc     esi
742
        cmp     byte[esi], 0x0a
742
        cmp     byte[esi], 0x0a
743
        jne     .chunk_hex_loop
743
        jne     .chunk_hex_loop
744
        dec     ecx
744
        dec     ecx
745
        jz      .need_more_data_chunked
745
        jz      .need_more_data_chunked
746
        inc     esi
746
        inc     esi
747
  .chunk_hex_loop:
747
  .chunk_hex_loop:
748
        lodsb
748
        lodsb
749
        sub     al, '0'
749
        sub     al, '0'
750
        jb      .chunk_hex_end
750
        jb      .chunk_hex_end
751
        cmp     al, 9
751
        cmp     al, 9
752
        jbe     .chunk_hex
752
        jbe     .chunk_hex
753
        sub     al, 'A' - '0' - 10
753
        sub     al, 'A' - '0' - 10
754
        jb      .chunk_hex_end
754
        jb      .chunk_hex_end
755
        cmp     al, 15
755
        cmp     al, 15
756
        jbe     .chunk_hex
756
        jbe     .chunk_hex
757
        sub     al, 'a' - 'A'
757
        sub     al, 'a' - 'A'
758
        cmp     al, 15
758
        cmp     al, 15
759
        ja      .chunk_hex_end
759
        ja      .chunk_hex_end
760
  .chunk_hex:
760
  .chunk_hex:
761
        shl     ebx, 4
761
        shl     ebx, 4
762
        add     bl, al
762
        add     bl, al
763
        dec     ecx
763
        dec     ecx
764
        jnz     .chunk_hex_loop
764
        jnz     .chunk_hex_loop
765
        jmp     .need_more_data_chunked
765
        jmp     .need_more_data_chunked
766
  .chunk_hex_end:
766
  .chunk_hex_end:
767
; Chunkline ends with a CR LF or simply LF
767
; Chunkline ends with a CR LF or simply LF
768
        dec     esi
768
        dec     esi
769
  .end_of_chunkline?:
769
  .end_of_chunkline?:
770
        lodsb
770
        lodsb
771
        cmp     al, 10                                  ; chunkline must always end with LF
771
        cmp     al, 10                                  ; chunkline must always end with LF
772
        je      .end_of_chunkline
772
        je      .end_of_chunkline
773
        dec     ecx
773
        dec     ecx
774
        jnz     .end_of_chunkline?
774
        jnz     .end_of_chunkline?
775
        xor     eax, eax
775
        xor     eax, eax
776
        jmp     .need_more_data_chunked                 ; chunkline is incomplete, request more data
776
        jmp     .need_more_data_chunked                 ; chunkline is incomplete, request more data
777
  .end_of_chunkline:
777
  .end_of_chunkline:
778
        DEBUGF  1, "Chunk of 0x%x bytes\n", ebx
778
        DEBUGF  1, "Chunk of 0x%x bytes\n", ebx
779
; If chunk size is 0, all chunks have been received.
779
; If chunk size is 0, all chunks have been received.
780
        test    ebx, ebx
780
        test    ebx, ebx
781
        jz      .got_all_data_chunked
781
        jz      .got_all_data_chunked
782
; Calculate how many data bytes we have received already
782
; Calculate how many data bytes we have received already
783
        mov     ecx, [ebp + http_msg.write_ptr]
783
        mov     ecx, [ebp + http_msg.write_ptr]
784
        sub     ecx, [ebp + http_msg.chunk_ptr]         ; ecx is now number of received data bytes
784
        sub     ecx, [ebp + http_msg.chunk_ptr]         ; ecx is now number of received data bytes
785
; Update content_received counter
785
; Update content_received counter
786
        add     [ebp + http_msg.content_received], ecx
786
        add     [ebp + http_msg.content_received], ecx
787
; Calculate new write ptr
787
; Calculate new write ptr
788
        mov     edx, esi
788
        mov     edx, esi
789
        sub     edx, [ebp + http_msg.chunk_ptr]         ; edx is now length of chunkline
789
        sub     edx, [ebp + http_msg.chunk_ptr]         ; edx is now length of chunkline
790
        sub     [ebp + http_msg.write_ptr], edx
790
        sub     [ebp + http_msg.write_ptr], edx
791
; Realloc buffer, make it 'chunksize' bigger.
791
; Realloc buffer, make it 'chunksize' bigger.
792
        lea     edx, [ebx + BUFFERSIZE]
792
        lea     edx, [ebx + BUFFERSIZE]
793
        mov     [ebp + http_msg.buffer_length], edx     ; remaining space in new buffer
793
        mov     [ebp + http_msg.buffer_length], edx     ; remaining space in new buffer
794
        add     edx, [ebp + http_msg.write_ptr]
794
        add     edx, [ebp + http_msg.write_ptr]
795
        sub     edx, [ebp + http_msg.content_ptr]
795
        sub     edx, [ebp + http_msg.content_ptr]
796
        DEBUGF  1, "Resizing buffer 0x%x, it will now be %u bytes\n", [ebp + http_msg.content_ptr], edx
796
        DEBUGF  1, "Resizing buffer 0x%x, it will now be %u bytes\n", [ebp + http_msg.content_ptr], edx
797
        invoke  mem.realloc, [ebp + http_msg.content_ptr], edx
797
        invoke  mem.realloc, [ebp + http_msg.content_ptr], edx
798
        DEBUGF  1, "New buffer = 0x%x\n", eax
798
        DEBUGF  1, "New buffer = 0x%x\n", eax
799
        or      eax, eax
799
        or      eax, eax
800
        jz      .err_no_ram
800
        jz      .err_no_ram
801
        call    recalculate_pointers                    ; Because it's possible that buffer begins on another address now
801
        call    recalculate_pointers                    ; Because it's possible that buffer begins on another address now
802
        add     esi, eax                                ; recalculate esi too!
802
        add     esi, eax                                ; recalculate esi too!
803
; Remove chunk header (aka chunkline) from the buffer by shifting all received data after chunkt_ptr to the left
803
; Remove chunk header (aka chunkline) from the buffer by shifting all received data after chunkt_ptr to the left
804
        mov     edi, [ebp + http_msg.chunk_ptr]
804
        mov     edi, [ebp + http_msg.chunk_ptr]
805
        rep movsb
805
        rep movsb
806
; Update chunk ptr to point to next chunk
806
; Update chunk ptr to point to next chunk
807
        add     [ebp + http_msg.chunk_ptr], ebx
807
        add     [ebp + http_msg.chunk_ptr], ebx
808
; Set number of received bytes to 0, we already updated content_received
808
; Set number of received bytes to 0, we already updated content_received
809
        xor     eax, eax
809
        xor     eax, eax
810
        jmp     .chunk_loop
810
        jmp     .chunk_loop
811
 
811
 
812
;--------------------------------------------------------------
812
;--------------------------------------------------------------
813
;
813
;
814
; end of proc code begins here
814
; end of proc code begins here
815
;
815
;
816
 
816
 
817
  .header_parsed:
817
  .header_parsed:
818
        ; Header was already parsed and connection isnt chunked.
818
        ; Header was already parsed and connection isnt chunked.
819
        ; Update content_received
819
        ; Update content_received
820
        add     [ebp + http_msg.content_received], eax
820
        add     [ebp + http_msg.content_received], eax
821
        ; If we received content-length parameter, check if we received all the data
821
        ; If we received content-length parameter, check if we received all the data
822
        test    [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
822
        test    [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
823
        jz      @f
823
        jz      @f
824
        mov     eax, [ebp + http_msg.content_received]
824
        mov     eax, [ebp + http_msg.content_received]
825
        cmp     eax, [ebp + http_msg.content_length]
825
        cmp     eax, [ebp + http_msg.content_length]
826
        jae     .got_all_data
826
        jae     .got_all_data
827
  @@:
827
  @@:
828
        cmp     [ebp + http_msg.buffer_length], 0
828
        cmp     [ebp + http_msg.buffer_length], 0
829
        je      .buffer_full
829
        je      .buffer_full
830
        ; Need more data
830
        ; Need more data
831
        popa
831
        popa
832
        xor     eax, eax
832
        xor     eax, eax
833
        dec     eax
833
        dec     eax
834
        ret
834
        ret
835
 
835
 
836
  .buffer_full:
836
  .buffer_full:
837
        ; Lets make it bigger..
837
        ; Lets make it bigger..
838
        mov     eax, [ebp + http_msg.write_ptr]
838
        mov     eax, [ebp + http_msg.write_ptr]
839
        add     eax, BUFFERSIZE
839
        add     eax, BUFFERSIZE
840
        sub     eax, [ebp + http_msg.content_ptr]
840
        sub     eax, [ebp + http_msg.content_ptr]
841
        invoke  mem.realloc, [ebp + http_msg.content_ptr], eax
841
        invoke  mem.realloc, [ebp + http_msg.content_ptr], eax
842
        or      eax, eax
842
        or      eax, eax
843
        jz      .err_no_ram
843
        jz      .err_no_ram
844
        call    recalculate_pointers
844
        call    recalculate_pointers
845
        mov     [ebp + http_msg.buffer_length], BUFFERSIZE
845
        mov     [ebp + http_msg.buffer_length], BUFFERSIZE
846
        ; Need more data
846
        ; Need more data
847
        popa
847
        popa
848
        xor     eax, eax
848
        xor     eax, eax
849
        dec     eax
849
        dec     eax
850
        ret
850
        ret
851
 
851
 
852
  .need_more_data_for_header:
852
  .need_more_data_for_header:
853
        cmp     [ebp + http_msg.buffer_length], 0
853
        cmp     [ebp + http_msg.buffer_length], 0
854
        je      .err_header                     ; It's just too damn long!
854
        je      .err_header                     ; It's just too damn long!
855
        ; Need more data
855
        ; Need more data
856
        popa
856
        popa
857
        xor     eax, eax
857
        xor     eax, eax
858
        dec     eax
858
        dec     eax
859
        ret
859
        ret
860
 
860
 
861
  .need_more_data_chunked:
861
  .need_more_data_chunked:
862
        ; We only got a partial chunk, or need more chunks, update content_received and request more data
862
        ; We only got a partial chunk, or need more chunks, update content_received and request more data
863
        add     [ebp + http_msg.content_received], eax
863
        add     [ebp + http_msg.content_received], eax
864
        popa
864
        popa
865
        xor     eax, eax
865
        xor     eax, eax
866
        dec     eax
866
        dec     eax
867
        ret
867
        ret
868
 
868
 
869
  .got_all_data_chunked:
869
  .got_all_data_chunked:
870
        ; Woohoo, we got all the chunked data, calculate total number of bytes received.
870
        ; Woohoo, we got all the chunked data, calculate total number of bytes received.
871
        mov     eax, [ebp + http_msg.chunk_ptr]
871
        mov     eax, [ebp + http_msg.chunk_ptr]
872
        sub     eax, [ebp + http_msg.content_ptr]
872
        sub     eax, [ebp + http_msg.content_ptr]
873
        mov     [ebp + http_msg.content_length], eax
873
        mov     [ebp + http_msg.content_length], eax
874
        mov     [ebp + http_msg.content_received], eax
874
        mov     [ebp + http_msg.content_received], eax
875
  .got_all_data:
875
  .got_all_data:
876
        DEBUGF  1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_received]
876
        DEBUGF  1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_received]
877
        or      [ebp + http_msg.flags], FLAG_GOT_ALL_DATA
877
        or      [ebp + http_msg.flags], FLAG_GOT_ALL_DATA
878
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
878
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
879
        mcall   close, [ebp + http_msg.socket]
879
        mcall   close, [ebp + http_msg.socket]
880
        popa
880
        popa
881
        xor     eax, eax
881
        xor     eax, eax
882
        ret
882
        ret
883
 
883
 
884
;--------------------------------------------------------------
884
;--------------------------------------------------------------
885
;
885
;
886
; error handeling code begins here
886
; error handeling code begins here
887
;
887
;
888
 
888
 
889
  .check_socket:
889
  .check_socket:
890
        cmp     ebx, EWOULDBLOCK
890
        cmp     ebx, EWOULDBLOCK
891
        jne     .err_socket
891
        jne     .err_socket
892
        mcall   26, 9
892
        mcall   26, 9
893
        sub     eax, [ebp + http_msg.timestamp]
893
        sub     eax, [ebp + http_msg.timestamp]
894
        cmp     eax, TIMEOUT
894
        cmp     eax, TIMEOUT
895
        ja      .err_timeout
895
        ja      .err_timeout
896
        ; Need more data
896
        ; Need more data
897
        popa
897
        popa
898
        xor     eax, eax
898
        xor     eax, eax
899
        dec     eax
899
        dec     eax
900
        ret
900
        ret
901
 
901
 
902
  .server_closed:
902
  .server_closed:
903
        DEBUGF  1, "server closed connection, transfer complete?\n"
903
        DEBUGF  1, "server closed connection, transfer complete?\n"
904
        test    [ebp + http_msg.flags], FLAG_GOT_HEADER
904
        test    [ebp + http_msg.flags], FLAG_GOT_HEADER
905
        jz      .err_server_closed
905
        jz      .err_server_closed
906
        test    [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
906
        test    [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
907
        jz      .got_all_data
907
        jz      .got_all_data
908
  .err_server_closed:
908
  .err_server_closed:
909
        pop     eax
909
        pop     eax
910
        DEBUGF  1, "ERROR: server closed connection unexpectedly\n"
910
        DEBUGF  1, "ERROR: server closed connection unexpectedly\n"
911
        or      [ebp + http_msg.flags], FLAG_TRANSFER_FAILED
911
        or      [ebp + http_msg.flags], FLAG_TRANSFER_FAILED
912
        jmp     .abort
912
        jmp     .abort
913
 
913
 
914
  .err_header:
914
  .err_header:
915
        pop     eax
915
        pop     eax
916
        DEBUGF  1, "ERROR: invalid header\n"
916
        DEBUGF  1, "ERROR: invalid header\n"
917
        or      [ebp + http_msg.flags], FLAG_INVALID_HEADER
917
        or      [ebp + http_msg.flags], FLAG_INVALID_HEADER
918
        jmp     .abort
918
        jmp     .abort
919
 
919
 
920
  .err_no_ram:
920
  .err_no_ram:
921
        DEBUGF  1, "ERROR: out of RAM\n"
921
        DEBUGF  1, "ERROR: out of RAM\n"
922
        or      [ebp + http_msg.flags], FLAG_NO_RAM
922
        or      [ebp + http_msg.flags], FLAG_NO_RAM
923
        jmp     .abort
923
        jmp     .abort
924
 
924
 
925
  .err_timeout:
925
  .err_timeout:
926
        DEBUGF  1, "ERROR: timeout\n"
926
        DEBUGF  1, "ERROR: timeout\n"
927
        or      [ebp + http_msg.flags], FLAG_TIMEOUT_ERROR
927
        or      [ebp + http_msg.flags], FLAG_TIMEOUT_ERROR
928
        jmp     .abort
928
        jmp     .abort
929
 
929
 
930
  .err_socket:
930
  .err_socket:
931
        DEBUGF  1, "ERROR: socket error %u\n", ebx
931
        DEBUGF  1, "ERROR: socket error %u\n", ebx
932
        or      [ebp + http_msg.flags], FLAG_SOCKET_ERROR
932
        or      [ebp + http_msg.flags], FLAG_SOCKET_ERROR
933
  .abort:
933
  .abort:
934
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
934
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
935
        mcall   close, [ebp + http_msg.socket]
935
        mcall   close, [ebp + http_msg.socket]
936
  .connection_closed:
936
  .connection_closed:
937
        popa
937
        popa
938
        xor     eax, eax
938
        xor     eax, eax
939
        ret
939
        ret
940
 
940
 
941
endp
941
endp
942
 
942
 
943
 
943
 
944
alloc_contentbuff:
944
alloc_contentbuff:
945
 
945
 
946
; Allocate content buffer
946
; Allocate content buffer
947
        invoke  mem.alloc, edx
947
        invoke  mem.alloc, edx
948
        or      eax, eax
948
        or      eax, eax
949
        jz      .no_ram
949
        jz      .no_ram
950
 
950
 
951
        DEBUGF  1, "Content buffer allocated: 0x%x\n", eax
951
        DEBUGF  1, "Content buffer allocated: 0x%x\n", eax
952
 
952
 
953
; Copy already received content into content buffer
953
; Copy already received content into content buffer
954
        mov     edi, eax
954
        mov     edi, eax
955
        lea     esi, [ebp + http_msg.http_header]
955
        lea     esi, [ebp + http_msg.http_header]
956
        add     esi, [ebp + http_msg.header_length]
956
        add     esi, [ebp + http_msg.header_length]
957
        mov     ecx, [ebp + http_msg.write_ptr]
957
        mov     ecx, [ebp + http_msg.write_ptr]
958
        sub     ecx, esi
958
        sub     ecx, esi
959
        mov     ebx, ecx
959
        mov     ebx, ecx
960
        rep movsb
960
        rep movsb
961
 
961
 
962
; Update pointers to point to new buffer
962
; Update pointers to point to new buffer
963
        mov     [ebp + http_msg.content_ptr], eax
963
        mov     [ebp + http_msg.content_ptr], eax
964
        mov     [ebp + http_msg.content_received], ebx
964
        mov     [ebp + http_msg.content_received], ebx
965
        sub     edx, ebx
965
        sub     edx, ebx
966
        mov     [ebp + http_msg.buffer_length], edx
966
        mov     [ebp + http_msg.buffer_length], edx
967
        add     eax, ebx
967
        add     eax, ebx
968
        mov     [ebp + http_msg.write_ptr], eax
968
        mov     [ebp + http_msg.write_ptr], eax
969
 
969
 
970
; Shrink header buffer
970
; Shrink header buffer
971
        mov     eax, http_msg.http_header
971
        mov     eax, http_msg.http_header
972
        add     eax, [ebp + http_msg.header_length]
972
        add     eax, [ebp + http_msg.header_length]
973
        invoke  mem.realloc, ebp, eax
973
        invoke  mem.realloc, ebp, eax
974
        or      eax, eax
974
        or      eax, eax
975
  .no_ram:
975
  .no_ram:
976
 
976
 
977
        ret
977
        ret
978
 
978
 
979
 
979
 
980
 
980
 
981
recalculate_pointers:
981
recalculate_pointers:
982
 
982
 
983
        sub     eax, [ebp + http_msg.content_ptr]
983
        sub     eax, [ebp + http_msg.content_ptr]
984
        jz      .done
984
        jz      .done
985
        add     [ebp + http_msg.content_ptr], eax
985
        add     [ebp + http_msg.content_ptr], eax
986
        add     [ebp + http_msg.write_ptr], eax
986
        add     [ebp + http_msg.write_ptr], eax
987
        add     [ebp + http_msg.chunk_ptr], eax
987
        add     [ebp + http_msg.chunk_ptr], eax
988
 
988
 
989
  .done:
989
  .done:
990
        ret
990
        ret
991
 
991
 
992
 
992
 
993
 
993
 
994
 
994
 
995
;;================================================================================================;;
995
;;================================================================================================;;
996
proc HTTP_free identifier ;///////////////////////////////////////////////////////////////////////;;
996
proc HTTP_free identifier ;///////////////////////////////////////////////////////////////////////;;
997
;;------------------------------------------------------------------------------------------------;;
997
;;------------------------------------------------------------------------------------------------;;
998
;? Free the http_msg structure                                                                    ;;
998
;? Free the http_msg structure                                                                    ;;
999
;;------------------------------------------------------------------------------------------------;;
999
;;------------------------------------------------------------------------------------------------;;
1000
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
1000
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
1001
;;------------------------------------------------------------------------------------------------;;
1001
;;------------------------------------------------------------------------------------------------;;
1002
;< none                                                                                           ;;
1002
;< none                                                                                           ;;
1003
;;================================================================================================;;
1003
;;================================================================================================;;
1004
        DEBUGF  1, "HTTP_free: 0x%x\n", [identifier]
1004
        DEBUGF  1, "HTTP_free: 0x%x\n", [identifier]
1005
        pusha
1005
        pusha
1006
        mov     ebp, [identifier]
1006
        mov     ebp, [identifier]
1007
 
1007
 
1008
        test    [ebp + http_msg.flags], FLAG_CONNECTED
1008
        test    [ebp + http_msg.flags], FLAG_CONNECTED
1009
        jz      .not_connected
1009
        jz      .not_connected
1010
 
1010
 
1011
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
1011
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
1012
        mcall   close, [ebp + http_msg.socket]
1012
        mcall   close, [ebp + http_msg.socket]
1013
 
1013
 
1014
  .not_connected:
1014
  .not_connected:
1015
        invoke  mem.free, ebp
1015
        invoke  mem.free, ebp
1016
 
1016
 
1017
        popa
1017
        popa
1018
        ret
1018
        ret
1019
 
1019
 
1020
endp
1020
endp
1021
 
1021
 
1022
 
1022
 
1023
 
1023
 
1024
;;================================================================================================;;
1024
;;================================================================================================;;
1025
proc HTTP_stop identifier ;///////////////////////////////////////////////////////////////////////;;
1025
proc HTTP_stop identifier ;///////////////////////////////////////////////////////////////////////;;
1026
;;------------------------------------------------------------------------------------------------;;
1026
;;------------------------------------------------------------------------------------------------;;
1027
;? Stops the open connection                                                                      ;;
1027
;? Stops the open connection                                                                      ;;
1028
;;------------------------------------------------------------------------------------------------;;
1028
;;------------------------------------------------------------------------------------------------;;
1029
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
1029
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
1030
;;------------------------------------------------------------------------------------------------;;
1030
;;------------------------------------------------------------------------------------------------;;
1031
;< none                                                                                           ;;
1031
;< none                                                                                           ;;
1032
;;================================================================================================;;
1032
;;================================================================================================;;
1033
 
1033
 
1034
        pusha
1034
        pusha
1035
        mov     ebp, [identifier]
1035
        mov     ebp, [identifier]
1036
 
1036
 
1037
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
1037
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
1038
        mcall   close, [ebp + http_msg.socket]
1038
        mcall   close, [ebp + http_msg.socket]
1039
 
1039
 
1040
        popa
1040
        popa
1041
        ret
1041
        ret
1042
 
1042
 
1043
endp
1043
endp
1044
 
1044
 
1045
 
1045
 
1046
 
1046
 
1047
;;================================================================================================;;
1047
;;================================================================================================;;
1048
proc HTTP_find_header_field identifier, headername ;//////////////////////////////////////////////;;
1048
proc HTTP_find_header_field identifier, headername ;//////////////////////////////////////////////;;
1049
;;------------------------------------------------------------------------------------------------;;
1049
;;------------------------------------------------------------------------------------------------;;
1050
;? Find a header field in the received HTTP header                                                ;;
1050
;? Find a header field in the received HTTP header                                                ;;
1051
;;------------------------------------------------------------------------------------------------;;
1051
;;------------------------------------------------------------------------------------------------;;
1052
;> identifier   = ptr to http_msg struct                                                          ;;
1052
;> identifier   = ptr to http_msg struct                                                          ;;
1053
;> headername   = ptr to ASCIIZ string containg field you want to find (must be in lowercase)     ;;
1053
;> headername   = ptr to ASCIIZ string containg field you want to find (must be in lowercase)     ;;
1054
;;------------------------------------------------------------------------------------------------;;
1054
;;------------------------------------------------------------------------------------------------;;
1055
;< eax = 0 (error) / ptr to content of the HTTP header field                                      ;;
1055
;< eax = 0 (error) / ptr to content of the HTTP header field                                      ;;
1056
;;================================================================================================;;
1056
;;================================================================================================;;
1057
        push    ebx ecx edx esi edi
1057
        push    ebx ecx edx esi edi
1058
 
1058
 
1059
        DEBUGF  1, "Find header field: %s\n", [headername]
1059
        DEBUGF  1, "Find header field: %s\n", [headername]
1060
 
1060
 
1061
        mov     ebx, [identifier]
1061
        mov     ebx, [identifier]
1062
        test    [ebx + http_msg.flags], FLAG_GOT_HEADER
1062
        test    [ebx + http_msg.flags], FLAG_GOT_HEADER
1063
        jz      .fail
1063
        jz      .fail
1064
 
1064
 
1065
        lea     edx, [ebx + http_msg.http_header]
1065
        lea     edx, [ebx + http_msg.http_header]
1066
        mov     ecx, edx
1066
        mov     ecx, edx
1067
        add     ecx, [ebx + http_msg.header_length]
1067
        add     ecx, [ebx + http_msg.header_length]
1068
 
1068
 
1069
  .restart:
1069
  .restart:
1070
        mov     esi, [headername]
1070
        mov     esi, [headername]
1071
        mov     edi, edx
1071
        mov     edi, edx
1072
  .loop:
1072
  .loop:
1073
        cmp     edi, ecx
1073
        cmp     edi, ecx
1074
        jae     .fail
1074
        jae     .fail
1075
        lodsb
1075
        lodsb
1076
        scasb
1076
        scasb
1077
        je      .loop
1077
        je      .loop
1078
        test    al, al
1078
        test    al, al
1079
        jz      .done?
1079
        jz      .done?
1080
  .next:
1080
  .next:
1081
        inc     edx
1081
        inc     edx
1082
        jmp     .restart
1082
        jmp     .restart
1083
 
1083
 
1084
  .not_done:
1084
  .not_done:
1085
        inc     edi
1085
        inc     edi
1086
  .done?:
1086
  .done?:
1087
        cmp     byte[edi-1], ':'
1087
        cmp     byte[edi-1], ':'
1088
        je      .almost_done
1088
        je      .almost_done
1089
        cmp     byte[edi-1], ' '
1089
        cmp     byte[edi-1], ' '
1090
        je      .not_done
1090
        je      .not_done
1091
        cmp     byte[edi-1], 9  ; tab
1091
        cmp     byte[edi-1], 9  ; tab
1092
        je      .not_done
1092
        je      .not_done
1093
 
1093
 
1094
        jmp     .next
1094
        jmp     .next
1095
 
1095
 
1096
  .almost_done:                 ; FIXME: buffer overflow?
1096
  .almost_done:                 ; FIXME: buffer overflow?
1097
        dec     edi
1097
        dec     edi
1098
        DEBUGF  1, "Found header field\n"
1098
        DEBUGF  1, "Found header field\n"
1099
  .spaceloop:
1099
  .spaceloop:
1100
        inc     edi
1100
        inc     edi
1101
        cmp     byte[edi], ' '
1101
        cmp     byte[edi], ' '
1102
        je      .spaceloop
1102
        je      .spaceloop
1103
        cmp     byte[edi], 9    ; tab
1103
        cmp     byte[edi], 9    ; tab
1104
        je      .spaceloop
1104
        je      .spaceloop
1105
 
1105
 
1106
        mov     eax, edi
1106
        mov     eax, edi
1107
        pop     edi esi edx ecx ebx
1107
        pop     edi esi edx ecx ebx
1108
        ret
1108
        ret
1109
 
1109
 
1110
  .fail:
1110
  .fail:
1111
        DEBUGF  1, "Header field not found\n"
1111
        DEBUGF  1, "Header field not found\n"
1112
        pop     edi esi edx ecx ebx
1112
        pop     edi esi edx ecx ebx
1113
        xor     eax, eax
1113
        xor     eax, eax
1114
        ret
1114
        ret
1115
 
1115
 
1116
endp
1116
endp
1117
 
1117
 
1118
 
1118
 
1119
 
1119
 
1120
;;================================================================================================;;
1120
;;================================================================================================;;
1121
proc URI_escape URI ;/////////////////////////////////////////////////////////////////////////////;;
1121
proc URI_escape URI ;/////////////////////////////////////////////////////////////////////////////;;
1122
;;------------------------------------------------------------------------------------------------;;
1122
;;------------------------------------------------------------------------------------------------;;
1123
;?                                                                                                ;;
1123
;?                                                                                                ;;
1124
;;------------------------------------------------------------------------------------------------;;
1124
;;------------------------------------------------------------------------------------------------;;
1125
;> URI = ptr to ASCIIZ URI                                                                        ;;
1125
;> URI = ptr to ASCIIZ URI                                                                        ;;
1126
;;------------------------------------------------------------------------------------------------;;
1126
;;------------------------------------------------------------------------------------------------;;
1127
;< eax = 0 (error) / ptr to ASCIIZ URI                                                            ;;
1127
;< eax = 0 (error) / ptr to ASCIIZ URI                                                            ;;
1128
;;================================================================================================;;
1128
;;================================================================================================;;
1129
 
1129
 
1130
        pusha
1130
        pusha
1131
 
1131
 
1132
        invoke  mem.alloc, URLMAXLEN
1132
        invoke  mem.alloc, URLMAXLEN
1133
        test    eax, eax
1133
        test    eax, eax
1134
        jz      .error
1134
        jz      .error
1135
        mov     [esp + 7 * 4], eax              ; return ptr in eax
1135
        mov     [esp + 7 * 4], eax              ; return ptr in eax
1136
        mov     esi, [URI]
1136
        mov     esi, [URI]
1137
        mov     edi, eax
1137
        mov     edi, eax
1138
        xor     ebx, ebx
1138
        xor     ebx, ebx
1139
        xor     ecx, ecx
1139
        xor     ecx, ecx
1140
  .loop:
1140
  .loop:
1141
        lodsb
1141
        lodsb
1142
        test    al, al
1142
        test    al, al
1143
        jz      .done
1143
        jz      .done
1144
 
1144
 
1145
        mov     cl, al
1145
        mov     cl, al
1146
        and     cl, 0x1f
1146
        and     cl, 0x1f
1147
        mov     bl, al
1147
        mov     bl, al
1148
        shr     bl, 5
1148
        shr     bl, 5
1149
        bt      dword[bits_must_escape + ebx], ecx
1149
        bt      dword[bits_must_escape + ebx], ecx
1150
        jc      .escape
1150
        jc      .escape
1151
 
1151
 
1152
        stosb
1152
        stosb
1153
        jmp     .loop
1153
        jmp     .loop
1154
 
1154
 
1155
  .escape:
1155
  .escape:
1156
        mov     al, '%'
1156
        mov     al, '%'
1157
        stosb
1157
        stosb
1158
        mov     bl, byte[esi-1]
1158
        mov     bl, byte[esi-1]
1159
        shr     bl, 4
1159
        shr     bl, 4
1160
        mov     al, byte[str_hex + ebx]
1160
        mov     al, byte[str_hex + ebx]
1161
        stosb
1161
        stosb
1162
        mov     bl, byte[esi-1]
1162
        mov     bl, byte[esi-1]
1163
        and     bl, 0x0f
1163
        and     bl, 0x0f
1164
        mov     al, byte[str_hex + ebx]
1164
        mov     al, byte[str_hex + ebx]
1165
        stosb
1165
        stosb
1166
        jmp     .loop
1166
        jmp     .loop
1167
 
1167
 
1168
 
1168
 
1169
  .done:
1169
  .done:
1170
        stosb
1170
        stosb
1171
 
1171
 
1172
        popa
1172
        popa
1173
        ret
1173
        ret
1174
 
1174
 
1175
  .error:
1175
  .error:
1176
        popa
1176
        popa
1177
        xor     eax, eax
1177
        xor     eax, eax
1178
        ret
1178
        ret
1179
 
1179
 
1180
endp
1180
endp
1181
 
1181
 
1182
 
1182
 
1183
 
1183
 
1184
;;================================================================================================;;
1184
;;================================================================================================;;
1185
proc URI_unescape URI ;///////////////////////////////////////////////////////////////////////////;;
1185
proc URI_unescape URI ;///////////////////////////////////////////////////////////////////////////;;
1186
;;------------------------------------------------------------------------------------------------;;
1186
;;------------------------------------------------------------------------------------------------;;
1187
;?                                                                                                ;;
1187
;?                                                                                                ;;
1188
;;------------------------------------------------------------------------------------------------;;
1188
;;------------------------------------------------------------------------------------------------;;
1189
;> URI = ptr to ASCIIZ URI                                                                        ;;
1189
;> URI = ptr to ASCIIZ URI                                                                        ;;
1190
;;------------------------------------------------------------------------------------------------;;
1190
;;------------------------------------------------------------------------------------------------;;
1191
;< eax = 0 (error) / ptr to ASCIIZ URI                                                            ;;
1191
;< eax = 0 (error) / ptr to ASCIIZ URI                                                            ;;
1192
;;================================================================================================;;
1192
;;================================================================================================;;
1193
 
1193
 
1194
        pusha
1194
        pusha
1195
 
1195
 
1196
        invoke  mem.alloc, URLMAXLEN
1196
        invoke  mem.alloc, URLMAXLEN
1197
        test    eax, eax
1197
        test    eax, eax
1198
        jz      .error
1198
        jz      .error
1199
        mov     [esp + 7 * 4], eax              ; return ptr in eax
1199
        mov     [esp + 7 * 4], eax              ; return ptr in eax
1200
        mov     esi, [URI]
1200
        mov     esi, [URI]
1201
        mov     edi, eax
1201
        mov     edi, eax
1202
  .loop:
1202
  .loop:
1203
        lodsb
1203
        lodsb
1204
        test    al, al
1204
        test    al, al
1205
        jz      .done
1205
        jz      .done
1206
 
1206
 
1207
        cmp     al, '%'
1207
        cmp     al, '%'
1208
        je      .unescape
1208
        je      .unescape
1209
 
1209
 
1210
        stosb
1210
        stosb
1211
        jmp     .loop
1211
        jmp     .loop
1212
 
1212
 
1213
  .unescape:
1213
  .unescape:
1214
        xor     ebx, ebx
1214
        xor     ebx, ebx
1215
        xor     ecx, ecx
1215
        xor     ecx, ecx
1216
  .unescape_nibble:
1216
  .unescape_nibble:
1217
        lodsb
1217
        lodsb
1218
        sub     al, '0'
1218
        sub     al, '0'
1219
        jb      .fail
1219
        jb      .fail
1220
        cmp     al, 9
1220
        cmp     al, 9
1221
        jbe     .nibble_ok
1221
        jbe     .nibble_ok
1222
        sub     al, 'A' - '0' - 10
1222
        sub     al, 'A' - '0' - 10
1223
        jb      .fail
1223
        jb      .fail
1224
        cmp     al, 15
1224
        cmp     al, 15
1225
        jbe     .nibble_ok
1225
        jbe     .nibble_ok
1226
        sub     al, 'a' - 'A'
1226
        sub     al, 'a' - 'A'
1227
        cmp     al, 15
1227
        cmp     al, 15
1228
        ja      .fail
1228
        ja      .fail
1229
  .nibble_ok:
1229
  .nibble_ok:
1230
        shl     bl, 8
1230
        shl     bl, 8
1231
        or      bl, al
1231
        or      bl, al
1232
        dec     ecx
1232
        dec     ecx
1233
        jc      .unescape_nibble
1233
        jc      .unescape_nibble
1234
        mov     al, bl
1234
        mov     al, bl
1235
        stosb
1235
        stosb
1236
        jmp     .loop
1236
        jmp     .loop
1237
 
1237
 
1238
  .fail:
1238
  .fail:
1239
        DEBUGF  1, "ERROR: invalid URI!\n"
1239
        DEBUGF  1, "ERROR: invalid URI!\n"
1240
        jmp     .loop
1240
        jmp     .loop
1241
 
1241
 
1242
  .done:
1242
  .done:
1243
        stosb
1243
        stosb
1244
 
1244
 
1245
        popa
1245
        popa
1246
        ret
1246
        ret
1247
 
1247
 
1248
  .error:
1248
  .error:
1249
        popa
1249
        popa
1250
        xor     eax, eax
1250
        xor     eax, eax
1251
        ret
1251
        ret
1252
 
1252
 
1253
endp
1253
endp
1254
 
1254
 
1255
 
1255
 
1256
 
1256
 
1257
 
1257
 
1258
 
1258
 
1259
;;================================================================================================;;
1259
;;================================================================================================;;
1260
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1260
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1261
;;================================================================================================;;
1261
;;================================================================================================;;
1262
;! Internal procedures section                                                                    ;;
1262
;! Internal procedures section                                                                    ;;
1263
;;                                                                                                ;;
1263
;;                                                                                                ;;
1264
;; NOTICE: These procedures do not follow stdcall conventions and thus may destroy any register.  ;;
1264
;; NOTICE: These procedures do not follow stdcall conventions and thus may destroy any register.  ;;
1265
;;================================================================================================;;
1265
;;================================================================================================;;
1266
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1266
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1267
;;================================================================================================;;
1267
;;================================================================================================;;
1268
 
1268
 
1269
 
1269
 
1270
 
1270
 
1271
 
1271
 
1272
;;================================================================================================;;
1272
;;================================================================================================;;
1273
proc open_connection hostname, port ;/////////////////////////////////////////////////////////////;;
1273
proc open_connection hostname, port ;/////////////////////////////////////////////////////////////;;
1274
;;------------------------------------------------------------------------------------------------;;
1274
;;------------------------------------------------------------------------------------------------;;
1275
;? Connects to a HTTP server                                                                      ;;
1275
;? Connects to a HTTP server                                                                      ;;
1276
;;------------------------------------------------------------------------------------------------;;
1276
;;------------------------------------------------------------------------------------------------;;
1277
;> hostname     = ptr to ASCIIZ hostname                                                          ;;
1277
;> hostname     = ptr to ASCIIZ hostname                                                          ;;
1278
;> port         = port (x86 byte order)                                                           ;;
1278
;> port         = port (x86 byte order)                                                           ;;
1279
;;------------------------------------------------------------------------------------------------;;
1279
;;------------------------------------------------------------------------------------------------;;
1280
;< eax = 0 (error) / socketnum                                                                    ;;
1280
;< eax = 0 (error) / socketnum                                                                    ;;
1281
;;================================================================================================;;
1281
;;================================================================================================;;
1282
 
1282
 
1283
locals
1283
locals
1284
        sockaddr        dd ?
1284
        sockaddr        dd ?
1285
        socketnum       dd ?
1285
        socketnum       dd ?
1286
endl
1286
endl
1287
 
1287
 
1288
        cmp     [proxyAddr], 0
1288
        cmp     [proxyAddr], 0
1289
        je      .no_proxy
1289
        je      .no_proxy
1290
 
1290
 
1291
        mov     [hostname], proxyAddr
1291
        mov     [hostname], proxyAddr
1292
 
1292
 
1293
        push    [proxyPort]
1293
        push    [proxyPort]
1294
        pop     [port]
1294
        pop     [port]
1295
  .no_proxy:
1295
  .no_proxy:
1296
 
1296
 
1297
; Resolve the hostname
1297
; Resolve the hostname
1298
        DEBUGF  1, "Resolving hostname\n"
1298
        DEBUGF  1, "Resolving hostname\n"
1299
        push    esp     ; reserve stack place
1299
        push    esp     ; reserve stack place
1300
        push    esp     ; fourth parameter
1300
        push    esp     ; fourth parameter
1301
        push    0       ; third parameter
1301
        push    0       ; third parameter
1302
        push    0       ; second parameter
1302
        push    0       ; second parameter
1303
        push    [hostname]
1303
        push    [hostname]
1304
        call    [getaddrinfo]
1304
        call    [getaddrinfo]
1305
        pop     esi
1305
        pop     esi
1306
        test    eax, eax
1306
        test    eax, eax
1307
        jnz     .error1
1307
        jnz     .error1
1308
 
1308
 
1309
; getaddrinfo returns addrinfo struct, make the pointer to sockaddr struct
1309
; getaddrinfo returns addrinfo struct, make the pointer to sockaddr struct
1310
        mov     esi, [esi + addrinfo.ai_addr]
1310
        mov     esi, [esi + addrinfo.ai_addr]
1311
        mov     [sockaddr], esi
1311
        mov     [sockaddr], esi
1312
        mov     eax, [esi + sockaddr_in.sin_addr]
1312
        mov     eax, [esi + sockaddr_in.sin_addr]
1313
        test    eax, eax
1313
        test    eax, eax
1314
        jz      .error2
1314
        jz      .error2
1315
 
1315
 
1316
        DEBUGF  1, "Server ip=%u.%u.%u.%u\n", \
1316
        DEBUGF  1, "Server ip=%u.%u.%u.%u\n", \
1317
        [esi + sockaddr_in.sin_addr]:1, [esi + sockaddr_in.sin_addr + 1]:1, \
1317
        [esi + sockaddr_in.sin_addr]:1, [esi + sockaddr_in.sin_addr + 1]:1, \
1318
        [esi + sockaddr_in.sin_addr + 2]:1, [esi + sockaddr_in.sin_addr + 3]:1
1318
        [esi + sockaddr_in.sin_addr + 2]:1, [esi + sockaddr_in.sin_addr + 3]:1
1319
 
1319
 
1320
        mov     [esi + sockaddr_in.sin_family], AF_INET4
1320
        mov     [esi + sockaddr_in.sin_family], AF_INET4
1321
        mov     eax, [port]
1321
        mov     eax, [port]
1322
        xchg    al, ah
1322
        xchg    al, ah
1323
        mov     [esi + sockaddr_in.sin_port], ax
1323
        mov     [esi + sockaddr_in.sin_port], ax
1324
 
1324
 
1325
; Connect to the server.
1325
; Connect to the server.
1326
        mcall   socket, AF_INET4, SOCK_STREAM, 0
1326
        mcall   socket, AF_INET4, SOCK_STREAM, 0
1327
        test    eax, eax
1327
        test    eax, eax
1328
        jz      .error2
1328
        jz      .error2
1329
        mov     [socketnum], eax
1329
        mov     [socketnum], eax
1330
        DEBUGF  1, "Socket: 0x%x\n", eax
1330
        DEBUGF  1, "Socket: 0x%x\n", eax
1331
 
1331
 
1332
        mcall   connect, [socketnum], [sockaddr], 18
1332
        mcall   connect, [socketnum], [sockaddr], 18
1333
        test    eax, eax
1333
        test    eax, eax
1334
        jnz     .error2
1334
        jnz     .error2
1335
        DEBUGF  1, "Socket is now connected.\n"
1335
        DEBUGF  1, "Socket is now connected.\n"
1336
 
1336
 
1337
; free allocated memory
1337
; free allocated memory
1338
        push    [sockaddr]
1338
        push    [sockaddr]
1339
        call    [freeaddrinfo]
1339
        call    [freeaddrinfo]
1340
 
1340
 
1341
        mov     eax, [socketnum]
1341
        mov     eax, [socketnum]
1342
        ret
1342
        ret
1343
 
1343
 
1344
  .error2:
1344
  .error2:
1345
 
1345
 
1346
; free allocated memory
1346
; free allocated memory
1347
        push    [sockaddr]
1347
        push    [sockaddr]
1348
        call    [freeaddrinfo]
1348
        call    [freeaddrinfo]
1349
 
1349
 
1350
  .error1:
1350
  .error1:
1351
        xor     eax, eax
1351
        xor     eax, eax
1352
        ret
1352
        ret
1353
 
1353
 
1354
endp
1354
endp
1355
 
1355
 
1356
 
1356
 
1357
;;================================================================================================;;
1357
;;================================================================================================;;
1358
proc parse_url URL ;//////////////////////////////////////////////////////////////////////////////;;
1358
proc parse_url URL ;//////////////////////////////////////////////////////////////////////////////;;
1359
;;------------------------------------------------------------------------------------------------;;
1359
;;------------------------------------------------------------------------------------------------;;
1360
;? Split a given URL into hostname and pageaddr                                                   ;;
1360
;? Split a given URL into hostname and pageaddr                                                   ;;
1361
;;------------------------------------------------------------------------------------------------;;
1361
;;------------------------------------------------------------------------------------------------;;
1362
;> URL = ptr to ASCIIZ URL                                                                        ;;
1362
;> URL = ptr to ASCIIZ URL                                                                        ;;
1363
;;------------------------------------------------------------------------------------------------;;
1363
;;------------------------------------------------------------------------------------------------;;
1364
;< eax = 0 (error) / ptr to ASCIIZ hostname                                                       ;;
1364
;< eax = 0 (error) / ptr to ASCIIZ hostname                                                       ;;
1365
;< ebx = ptr to ASCIIZ pageaddr                                                                   ;;
1365
;< ebx = ptr to ASCIIZ pageaddr                                                                   ;;
1366
;< ecx = port number                                                                              ;;
1366
;< ecx = port number                                                                              ;;
1367
;;================================================================================================;;
1367
;;================================================================================================;;
1368
 
1368
 
1369
locals
1369
locals
1370
        urlsize         dd ?
1370
        urlsize         dd ?
1371
        hostname        dd ?
1371
        hostname        dd ?
1372
        pageaddr        dd ?
1372
        pageaddr        dd ?
1373
        port            dd ?
1373
        port            dd ?
1374
endl
1374
endl
1375
 
1375
 
1376
        DEBUGF  1, "parsing URL: %s\n", [URL]
1376
        DEBUGF  1, "parsing URL: %s\n", [URL]
1377
 
1377
 
1378
; remove any leading protocol text
1378
; remove any leading protocol text
1379
        mov     esi, [URL]
1379
        mov     esi, [URL]
1380
        mov     ecx, URLMAXLEN
1380
        mov     ecx, URLMAXLEN
1381
        mov     ax, '//'
1381
        mov     ax, '//'
1382
  .loop1:
1382
  .loop1:
1383
        cmp     byte[esi], 0            ; end of URL?
1383
        cmp     byte[esi], 0            ; end of URL?
1384
        je      .url_ok                 ; yep, so not found
1384
        je      .url_ok                 ; yep, so not found
1385
        cmp     [esi], ax
1385
        cmp     [esi], ax
1386
        je      .skip_proto
1386
        je      .skip_proto
1387
        inc     esi
1387
        inc     esi
1388
        dec     ecx
1388
        dec     ecx
1389
        jnz     .loop1
1389
        jnz     .loop1
1390
        jmp     .invalid
1390
        jmp     .invalid
1391
 
1391
 
1392
  .skip_proto:
1392
  .skip_proto:
1393
        inc     esi                     ; skip the two '/'
1393
        inc     esi                     ; skip the two '/'
1394
        inc     esi
1394
        inc     esi
1395
        mov     [URL], esi              ; update pointer so it skips protocol
1395
        mov     [URL], esi              ; update pointer so it skips protocol
1396
        jmp     .loop1                  ; we still need to find the length of the URL
1396
        jmp     .loop1                  ; we still need to find the length of the URL
1397
 
1397
 
1398
  .url_ok:
1398
  .url_ok:
1399
        sub     esi, [URL]              ; calculate total length of URL
1399
        sub     esi, [URL]              ; calculate total length of URL
1400
        mov     [urlsize], esi
1400
        mov     [urlsize], esi
1401
 
1401
 
1402
 
1402
 
1403
; now look for page delimiter - it's a '/' character
1403
; now look for page delimiter - it's a '/' character
1404
        mov     ecx, esi                ; URL length
1404
        mov     ecx, esi                ; URL length
1405
        mov     edi, [URL]
1405
        mov     edi, [URL]
1406
        mov     al, '/'
1406
        mov     al, '/'
1407
        repne   scasb
1407
        repne   scasb
1408
        jne     @f
1408
        jne     @f
1409
        dec     edi                     ; return one char, '/' must be part of the pageaddr
1409
        dec     edi                     ; return one char, '/' must be part of the pageaddr
1410
        inc     ecx                     ;
1410
        inc     ecx                     ;
1411
  @@:
1411
  @@:
1412
        push    ecx edi                 ; remember the pointer and length of pageaddr
1412
        push    ecx edi                 ; remember the pointer and length of pageaddr
1413
 
1413
 
1414
 
1414
 
1415
; Create new buffer and put hostname in it.
1415
; Create new buffer and put hostname in it.
1416
        mov     ecx, edi
1416
        mov     ecx, edi
1417
        sub     ecx, [URL]
1417
        sub     ecx, [URL]
1418
        inc     ecx                     ; we will add a 0 byte at the end
1418
        inc     ecx                     ; we will add a 0 byte at the end
1419
        invoke  mem.alloc, ecx
1419
        invoke  mem.alloc, ecx
1420
        or      eax, eax
1420
        or      eax, eax
1421
        jz      .no_mem
1421
        jz      .no_mem
1422
 
1422
 
1423
        mov     [hostname], eax         ; copy hostname to buffer
1423
        mov     [hostname], eax         ; copy hostname to buffer
1424
        mov     edi, eax
1424
        mov     edi, eax
1425
        mov     esi, [URL]
1425
        mov     esi, [URL]
1426
        dec     ecx
1426
        dec     ecx
1427
        rep     movsb
1427
        rep     movsb
1428
        xor     al, al
1428
        xor     al, al
1429
        stosb
1429
        stosb
1430
 
1430
 
1431
; Check if user provided a port, and convert it if so.
1431
; Check if user provided a port, and convert it if so.
1432
        mov     esi, [hostname]
1432
        mov     esi, [hostname]
1433
        mov     [port], 80              ; default port if user didnt provide one
1433
        mov     [port], 80              ; default port if user didnt provide one
1434
  .portloop:
1434
  .portloop:
1435
        lodsb
1435
        lodsb
1436
        test    al, al
1436
        test    al, al
1437
        jz      .no_port
1437
        jz      .no_port
1438
        cmp     al, ':'
1438
        cmp     al, ':'
1439
        jne     .portloop
1439
        jne     .portloop
1440
 
1440
 
1441
        push    esi
1441
        push    esi
1442
        call    ascii_dec_ebx
1442
        call    ascii_dec_ebx
1443
        pop     edi
1443
        pop     edi
1444
        cmp     byte[esi-1], 0
1444
        cmp     byte[esi-1], 0
1445
        jne     .invalid
1445
        jne     .invalid
1446
        cmp     [proxyAddr], 0          ; remove port number from hostname
1446
        cmp     [proxyAddr], 0          ; remove port number from hostname
1447
        jne     @f                      ; unless when we are using proxy
1447
        jne     @f                      ; unless when we are using proxy
1448
        mov     byte[edi-1], 0
1448
        mov     byte[edi-1], 0
1449
  @@:
1449
  @@:
1450
        test    ebx, ebx
1450
        test    ebx, ebx
1451
        je      .invalid
1451
        je      .invalid
1452
        cmp     ebx, 0xffff
1452
        cmp     ebx, 0xffff
1453
        ja      .invalid
1453
        ja      .invalid
1454
        mov     [port], ebx
1454
        mov     [port], ebx
1455
  .no_port:
1455
  .no_port:
1456
 
1456
 
1457
 
1457
 
1458
; Did user provide a pageaddr?
1458
; Did user provide a pageaddr?
1459
        mov     [pageaddr], str_slash   ; assume there is no pageaddr
1459
        mov     [pageaddr], str_slash   ; assume there is no pageaddr
1460
        pop     esi ecx
1460
        pop     esi ecx
1461
        test    ecx, ecx
1461
        test    ecx, ecx
1462
        jz      .no_page
1462
        jz      .no_page
1463
 
1463
 
1464
; Create new buffer and put pageaddr into it.
1464
; Create new buffer and put pageaddr into it.
1465
        inc     ecx                     ; we will add a 0 byte at the end
1465
        inc     ecx                     ; we will add a 0 byte at the end
1466
        invoke  mem.alloc, ecx
1466
        invoke  mem.alloc, ecx
1467
        or      eax, eax
1467
        or      eax, eax
1468
        jz      .no_mem
1468
        jz      .no_mem
1469
 
1469
 
1470
        mov     [pageaddr], eax         ; copy pageaddr to buffer
1470
        mov     [pageaddr], eax         ; copy pageaddr to buffer
1471
        mov     edi, eax
1471
        mov     edi, eax
1472
        dec     ecx
1472
        dec     ecx
1473
        rep     movsb
1473
        rep     movsb
1474
        xor     al, al
1474
        xor     al, al
1475
        stosb
1475
        stosb
1476
 
1476
 
1477
  .no_page:
1477
  .no_page:
1478
        mov     eax, [hostname]
1478
        mov     eax, [hostname]
1479
        mov     ebx, [pageaddr]
1479
        mov     ebx, [pageaddr]
1480
        mov     ecx, [port]
1480
        mov     ecx, [port]
1481
 
1481
 
1482
        DEBUGF  1, "hostname: %s\n", eax
1482
        DEBUGF  1, "hostname: %s\n", eax
1483
        DEBUGF  1, "pageaddr: %s\n", ebx
1483
        DEBUGF  1, "pageaddr: %s\n", ebx
1484
        DEBUGF  1, "port: %u\n", ecx
1484
        DEBUGF  1, "port: %u\n", ecx
1485
 
1485
 
1486
        ret
1486
        ret
1487
 
1487
 
1488
  .no_mem:
1488
  .no_mem:
1489
        DEBUGF  1, "Out of memory!\n"
1489
        DEBUGF  1, "Out of memory!\n"
1490
        xor     eax, eax
1490
        xor     eax, eax
1491
        ret
1491
        ret
1492
 
1492
 
1493
  .invalid:
1493
  .invalid:
1494
        DEBUGF  1, "Invalid URL!\n"
1494
        DEBUGF  1, "Invalid URL!\n"
1495
        xor     eax, eax
1495
        xor     eax, eax
1496
        ret
1496
        ret
1497
 
1497
 
1498
endp
1498
endp
1499
 
1499
 
1500
 
1500
 
1501
 
1501
 
1502
 
1502
 
1503
 
1503
 
1504
;;================================================================================================;;
1504
;;================================================================================================;;
1505
proc append_proxy_auth_header ;///////////////////////////////////////////////////////////////////;;
1505
proc append_proxy_auth_header ;///////////////////////////////////////////////////////////////////;;
1506
;;------------------------------------------------------------------------------------------------;;
1506
;;------------------------------------------------------------------------------------------------;;
1507
;? Appends the proxy authentication header                                                        ;;
1507
;? Appends the proxy authentication header                                                        ;;
1508
;;------------------------------------------------------------------------------------------------;;
1508
;;------------------------------------------------------------------------------------------------;;
1509
;> /                                                                                              ;;
1509
;> /                                                                                              ;;
1510
;;------------------------------------------------------------------------------------------------;;
1510
;;------------------------------------------------------------------------------------------------;;
1511
;< /                                                                                              ;;
1511
;< /                                                                                              ;;
1512
;;================================================================================================;;
1512
;;================================================================================================;;
1513
        mov     esi, str_proxy_auth
1513
        mov     esi, str_proxy_auth
1514
        mov     ecx, str_proxy_auth.length
1514
        mov     ecx, str_proxy_auth.length
1515
        rep     movsb
1515
        rep     movsb
1516
; base64-encode string :
1516
; base64-encode string :
1517
        mov     esi, proxyUser
1517
        mov     esi, proxyUser
1518
 
1518
 
1519
apah000:
1519
apah000:
1520
        lodsb
1520
        lodsb
1521
        test    al, al
1521
        test    al, al
1522
        jz      apah001
1522
        jz      apah001
1523
        call    encode_base64_byte
1523
        call    encode_base64_byte
1524
        jmp     apah000
1524
        jmp     apah000
1525
 
1525
 
1526
apah001:
1526
apah001:
1527
        mov     al, ':'
1527
        mov     al, ':'
1528
        call    encode_base64_byte
1528
        call    encode_base64_byte
1529
        mov     esi, proxyPassword
1529
        mov     esi, proxyPassword
1530
 
1530
 
1531
apah002:
1531
apah002:
1532
        lodsb
1532
        lodsb
1533
        test    al, al
1533
        test    al, al
1534
        jz      apah003
1534
        jz      apah003
1535
        call    encode_base64_byte
1535
        call    encode_base64_byte
1536
        jmp     apah002
1536
        jmp     apah002
1537
 
1537
 
1538
apah003:
1538
apah003:
1539
        call    encode_base64_final
1539
        call    encode_base64_final
1540
        ret
1540
        ret
1541
 
1541
 
1542
encode_base64_byte:
1542
encode_base64_byte:
1543
        inc     ecx
1543
        inc     ecx
1544
        shl     edx, 8
1544
        shl     edx, 8
1545
        mov     dl, al
1545
        mov     dl, al
1546
        cmp     ecx, 3
1546
        cmp     ecx, 3
1547
        je      ebb001
1547
        je      ebb001
1548
        ret
1548
        ret
1549
 
1549
 
1550
ebb001:
1550
ebb001:
1551
        shl     edx, 8
1551
        shl     edx, 8
1552
        inc     ecx
1552
        inc     ecx
1553
 
1553
 
1554
ebb002:
1554
ebb002:
1555
        rol     edx, 6
1555
        rol     edx, 6
1556
        xor     eax, eax
1556
        xor     eax, eax
1557
        xchg    al, dl
1557
        xchg    al, dl
1558
        mov     al, [base64_table+eax]
1558
        mov     al, [base64_table+eax]
1559
        stosb
1559
        stosb
1560
        loop    ebb002
1560
        loop    ebb002
1561
        ret
1561
        ret
1562
 
1562
 
1563
encode_base64_final:
1563
encode_base64_final:
1564
        mov     al, 0
1564
        mov     al, 0
1565
        test    ecx, ecx
1565
        test    ecx, ecx
1566
        jz      ebf000
1566
        jz      ebf000
1567
        call    encode_base64_byte
1567
        call    encode_base64_byte
1568
        test    ecx, ecx
1568
        test    ecx, ecx
1569
        jz      ebf001
1569
        jz      ebf001
1570
        call    encode_base64_byte
1570
        call    encode_base64_byte
1571
        mov     byte [edi-2], '='
1571
        mov     byte [edi-2], '='
1572
 
1572
 
1573
ebf001:
1573
ebf001:
1574
        mov     byte [edi-1], '='
1574
        mov     byte [edi-1], '='
1575
 
1575
 
1576
ebf000:
1576
ebf000:
1577
        ret
1577
        ret
1578
 
1578
 
1579
endp
1579
endp
1580
 
1580
 
1581
 
1581
 
1582
;;================================================================================================;;
1582
;;================================================================================================;;
1583
proc eax_ascii_dec ;//////////////////////////////////////////////////////////////////////////////;;
1583
proc eax_ascii_dec ;//////////////////////////////////////////////////////////////////////////////;;
1584
;;------------------------------------------------------------------------------------------------;;
1584
;;------------------------------------------------------------------------------------------------;;
1585
;? Convert eax to ASCII decimal number                                                            ;;
1585
;? Convert eax to ASCII decimal number                                                            ;;
1586
;;------------------------------------------------------------------------------------------------;;
1586
;;------------------------------------------------------------------------------------------------;;
1587
;> eax = number                                                                                   ;;
1587
;> eax = number                                                                                   ;;
1588
;> edi = ptr where to write ASCII decimal number                                                  ;;
1588
;> edi = ptr where to write ASCII decimal number                                                  ;;
1589
;;------------------------------------------------------------------------------------------------;;
1589
;;------------------------------------------------------------------------------------------------;;
1590
;< /                                                                                              ;;
1590
;< /                                                                                              ;;
1591
;;================================================================================================;;
1591
;;================================================================================================;;
1592
 
1592
 
1593
        push    -'0'
1593
        push    -'0'
1594
        mov     ecx, 10
1594
        mov     ecx, 10
1595
  .loop:
1595
  .loop:
1596
        xor     edx, edx
1596
        xor     edx, edx
1597
        div     ecx
1597
        div     ecx
1598
        add     dl, '0'
-
 
1599
        push    edx
1598
        push    edx
1600
        test    eax, eax
1599
        test    eax, eax
1601
        jnz     .loop
1600
        jnz     .loop
1602
 
1601
 
1603
  .loop2:
1602
  .loop2:
1604
        pop     eax
1603
        pop     eax
1605
        add     al, '0'
1604
        add     al, '0'
1606
        jz      .done
1605
        jz      .done
1607
        stosb
1606
        stosb
1608
        jmp     .loop2
1607
        jmp     .loop2
1609
  .done:
1608
  .done:
1610
 
1609
 
1611
        ret
1610
        ret
1612
 
1611
 
1613
endp
1612
endp
1614
 
1613
 
1615
 
1614
 
1616
;;================================================================================================;;
1615
;;================================================================================================;;
1617
proc ascii_dec_ebx ;//////////////////////////////////////////////////////////////////////////////;;
1616
proc ascii_dec_ebx ;//////////////////////////////////////////////////////////////////////////////;;
1618
;;------------------------------------------------------------------------------------------------;;
1617
;;------------------------------------------------------------------------------------------------;;
1619
;? Convert ASCII decimal number to ebx                                                            ;;
1618
;? Convert ASCII decimal number to ebx                                                            ;;
1620
;;------------------------------------------------------------------------------------------------;;
1619
;;------------------------------------------------------------------------------------------------;;
1621
;> esi = ptr where to read ASCII decimal number                                                   ;;
1620
;> esi = ptr where to read ASCII decimal number                                                   ;;
1622
;;------------------------------------------------------------------------------------------------;;
1621
;;------------------------------------------------------------------------------------------------;;
1623
;> ebx = number                                                                                   ;;
1622
;> ebx = number                                                                                   ;;
1624
;;================================================================================================;;
1623
;;================================================================================================;;
1625
 
1624
 
1626
        xor     eax, eax
1625
        xor     eax, eax
1627
        xor     ebx, ebx
1626
        xor     ebx, ebx
1628
  .loop:
1627
  .loop:
1629
        lodsb
1628
        lodsb
1630
        sub     al, '0'
1629
        sub     al, '0'
1631
        jb      .done
1630
        jb      .done
1632
        cmp     al, 9
1631
        cmp     al, 9
1633
        ja      .done
1632
        ja      .done
1634
        lea     ebx, [ebx + 4*ebx]
1633
        lea     ebx, [ebx + 4*ebx]
1635
        shl     ebx, 1
1634
        shl     ebx, 1
1636
        add     ebx, eax
1635
        add     ebx, eax
1637
        jmp     .loop
1636
        jmp     .loop
1638
  .done:
1637
  .done:
1639
 
1638
 
1640
        ret
1639
        ret
1641
 
1640
 
1642
endp
1641
endp
1643
 
1642
 
1644
 
1643
 
1645
;;================================================================================================;;
1644
;;================================================================================================;;
1646
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1645
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1647
;;================================================================================================;;
1646
;;================================================================================================;;
1648
;! Imported functions section                                                                     ;;
1647
;! Imported functions section                                                                     ;;
1649
;;================================================================================================;;
1648
;;================================================================================================;;
1650
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1649
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1651
;;================================================================================================;;
1650
;;================================================================================================;;
1652
 
1651
 
1653
 
1652
 
1654
align 16
1653
align 16
1655
@IMPORT:
1654
@IMPORT:
1656
 
1655
 
1657
library \
1656
library \
1658
        libini, 'libini.obj', \
1657
        libini, 'libini.obj', \
1659
        network, 'network.obj'
1658
        network, 'network.obj'
1660
 
1659
 
1661
import  libini, \
1660
import  libini, \
1662
        ini.get_str, 'ini_get_str', \
1661
        ini.get_str, 'ini_get_str', \
1663
        ini.get_int, 'ini_get_int'
1662
        ini.get_int, 'ini_get_int'
1664
 
1663
 
1665
import  network,\
1664
import  network,\
1666
        getaddrinfo, 'getaddrinfo',\
1665
        getaddrinfo, 'getaddrinfo',\
1667
        freeaddrinfo,  'freeaddrinfo',\
1666
        freeaddrinfo,  'freeaddrinfo',\
1668
        inet_ntoa, 'inet_ntoa'
1667
        inet_ntoa, 'inet_ntoa'
1669
 
1668
 
1670
;;===========================================================================;;
1669
;;===========================================================================;;
1671
;;///////////////////////////////////////////////////////////////////////////;;
1670
;;///////////////////////////////////////////////////////////////////////////;;
1672
;;===========================================================================;;
1671
;;===========================================================================;;
1673
;! Exported functions section                                                ;;
1672
;! Exported functions section                                                ;;
1674
;;===========================================================================;;
1673
;;===========================================================================;;
1675
;;///////////////////////////////////////////////////////////////////////////;;
1674
;;///////////////////////////////////////////////////////////////////////////;;
1676
;;===========================================================================;;
1675
;;===========================================================================;;
1677
 
1676
 
1678
 
1677
 
1679
align 4
1678
align 4
1680
@EXPORT:
1679
@EXPORT:
1681
export  \
1680
export  \
1682
        lib_init                , 'lib_init'            , \
1681
        lib_init                , 'lib_init'            , \
1683
        0x00010001              , 'version'             , \
1682
        0x00010001              , 'version'             , \
1684
        HTTP_get                , 'get'                 , \
1683
        HTTP_get                , 'get'                 , \
1685
        HTTP_head               , 'head'                , \
1684
        HTTP_head               , 'head'                , \
1686
        HTTP_post               , 'post'                , \
1685
        HTTP_post               , 'post'                , \
1687
        HTTP_find_header_field  , 'find_header_field'   , \
1686
        HTTP_find_header_field  , 'find_header_field'   , \
1688
        HTTP_process            , 'process'             , \
1687
        HTTP_process            , 'process'             , \
1689
        HTTP_free               , 'free'                , \
1688
        HTTP_free               , 'free'                , \
1690
        HTTP_stop               , 'stop'                , \
1689
        HTTP_stop               , 'stop'                , \
1691
        URI_escape              , 'escape'              , \
1690
        URI_escape              , 'escape'              , \
1692
        URI_unescape            , 'unescape'
1691
        URI_unescape            , 'unescape'
1693
 
1692
 
1694
;        HTTP_put                , 'put'                 , \
1693
;        HTTP_put                , 'put'                 , \
1695
;        HTTP_delete             , 'delete'              , \
1694
;        HTTP_delete             , 'delete'              , \
1696
;        HTTP_trace              , 'trace'               , \
1695
;        HTTP_trace              , 'trace'               , \
1697
;        HTTP_connect            , 'connect'             , \
1696
;        HTTP_connect            , 'connect'             , \
1698
 
1697
 
1699
 
1698
 
1700
 
1699
 
1701
section '.data' data readable writable align 16
1700
section '.data' data readable writable align 16
1702
 
1701
 
1703
inifile         db '/sys/settings/network.ini', 0
1702
inifile         db '/sys/settings/network.ini', 0
1704
 
1703
 
1705
sec_proxy:
1704
sec_proxy:
1706
key_proxy       db 'proxy', 0
1705
key_proxy       db 'proxy', 0
1707
key_proxyport   db 'port', 0
1706
key_proxyport   db 'port', 0
1708
key_user        db 'user', 0
1707
key_user        db 'user', 0
1709
key_password    db 'password', 0
1708
key_password    db 'password', 0
1710
 
1709
 
1711
str_http11      db ' HTTP/1.1', 13, 10, 'Host: '
1710
str_http11      db ' HTTP/1.1', 13, 10, 'Host: '
1712
  .length       = $ - str_http11
1711
  .length       = $ - str_http11
1713
str_post_cl     db 13, 10, 'Content-Length: '
1712
str_post_cl     db 13, 10, 'Content-Length: '
1714
  .length       = $ - str_post_cl
1713
  .length       = $ - str_post_cl
1715
str_post_ct     db 13, 10, 'Content-Type: '
1714
str_post_ct     db 13, 10, 'Content-Type: '
1716
  .length       = $ - str_post_ct
1715
  .length       = $ - str_post_ct
1717
str_proxy_auth  db 13, 10, 'Proxy-Authorization: Basic '
1716
str_proxy_auth  db 13, 10, 'Proxy-Authorization: Basic '
1718
  .length       = $ - str_proxy_auth
1717
  .length       = $ - str_proxy_auth
1719
str_close       db 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
1718
str_close       db 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
1720
  .length       = $ - str_close
1719
  .length       = $ - str_close
1721
 
1720
 
1722
str_http        db 'http://', 0
1721
str_http        db 'http://', 0
1723
 
1722
 
1724
base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
1723
base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
1725
                db '0123456789+/'
1724
                db '0123456789+/'
1726
 
1725
 
1727
str_cl          db 'content-length', 0
1726
str_cl          db 'content-length', 0
1728
str_slash       db '/', 0
1727
str_slash       db '/', 0
1729
str_te          db 'transfer-encoding', 0
1728
str_te          db 'transfer-encoding', 0
1730
str_get         db 'GET ', 0
1729
str_get         db 'GET ', 0
1731
str_head        db 'HEAD ', 0
1730
str_head        db 'HEAD ', 0
1732
str_post        db 'POST ', 0
1731
str_post        db 'POST ', 0
1733
 
1732
 
1734
bits_must_escape:
1733
bits_must_escape:
1735
dd      0xffffffff                                                      ; 00-1F
1734
dd      0xffffffff                                                      ; 00-1F
1736
dd      1 shl 0 + 1 shl 2 + 1 shl 3 + 1 shl 5 + 1 shl 28 + 1 shl 30     ; "#%<>
1735
dd      1 shl 0 + 1 shl 2 + 1 shl 3 + 1 shl 5 + 1 shl 28 + 1 shl 30     ; "#%<>
1737
dd      1 shl 27 + 1 shl 28 + 1 shl 29 + 1 shl 30                       ;[\]^
1736
dd      1 shl 27 + 1 shl 28 + 1 shl 29 + 1 shl 30                       ;[\]^
1738
dd      1 shl 0 + 1 shl 27 + 1 shl 28 + 1 shl 29 + 1 shl 31             ;`{|} DEL
1737
dd      1 shl 0 + 1 shl 27 + 1 shl 28 + 1 shl 29 + 1 shl 31             ;`{|} DEL
1739
 
1738
 
1740
dd      0xffffffff
1739
dd      0xffffffff
1741
dd      0xffffffff
1740
dd      0xffffffff
1742
dd      0xffffffff
1741
dd      0xffffffff
1743
dd      0xffffffff
1742
dd      0xffffffff
1744
 
1743
 
1745
str_hex:
1744
str_hex:
1746
db '0123456789ABCDEF'
1745
db '0123456789ABCDEF'
1747
 
1746
 
1748
include_debug_strings
1747
include_debug_strings
1749
 
1748
 
1750
; uninitialized data
1749
; uninitialized data
1751
mem.alloc       dd ?
1750
mem.alloc       dd ?
1752
mem.free        dd ?
1751
mem.free        dd ?
1753
mem.realloc     dd ?
1752
mem.realloc     dd ?
1754
dll.load        dd ?
1753
dll.load        dd ?
1755
 
1754
 
1756
proxyAddr       rb 256
1755
proxyAddr       rb 256
1757
proxyUser       rb 256
1756
proxyUser       rb 256
1758
proxyPassword   rb 256
1757
proxyPassword   rb 256
1759
proxyPort       dd ?
1758
proxyPort       dd ?