Subversion Repositories Kolibri OS

Rev

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

Rev 4206 Rev 4207
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2013. 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
;;                                                                 ;;
9
;;                                                                 ;;
10
;;         GNU GENERAL PUBLIC LICENSE                              ;;
10
;;         GNU GENERAL PUBLIC LICENSE                              ;;
11
;;          Version 2, June 1991                                   ;;
11
;;          Version 2, June 1991                                   ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
14
 
15
; references:
15
; references:
16
; "HTTP made really easy", http://www.jmarshall.com/easy/http/
16
; "HTTP made really easy", http://www.jmarshall.com/easy/http/
17
; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616
17
; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616
18
 
18
 
19
 
19
 
20
        URLMAXLEN       = 65535
20
        URLMAXLEN       = 65535
21
        BUFFERSIZE      = 4096
21
        BUFFERSIZE      = 4096
22
        TIMEOUT         = 1000  ; in 1/100 s
22
        TIMEOUT         = 1000  ; in 1/100 s
23
 
23
 
24
        __DEBUG__       = 1
24
        __DEBUG__       = 1
25
        __DEBUG_LEVEL__ = 1
25
        __DEBUG_LEVEL__ = 1
26
 
26
 
27
 
27
 
28
format MS COFF
28
format MS COFF
29
 
29
 
30
public @EXPORT as 'EXPORTS'
30
public @EXPORT as 'EXPORTS'
31
 
31
 
32
include '../../../struct.inc'
32
include '../../../struct.inc'
33
include '../../../proc32.inc'
33
include '../../../proc32.inc'
34
include '../../../macros.inc'
34
include '../../../macros.inc'
35
purge section,mov,add,sub
35
purge section,mov,add,sub
36
include '../../../debug-fdo.inc'
36
include '../../../debug-fdo.inc'
37
 
37
 
38
include '../../../network.inc'
38
include '../../../network.inc'
39
include 'http.inc'
39
include 'http.inc'
40
 
40
 
41
virtual at 0
41
virtual at 0
42
        http_msg http_msg
42
        http_msg http_msg
43
end virtual
43
end virtual
44
 
44
 
45
macro copy_till_zero {
45
macro copy_till_zero {
46
  @@:
46
  @@:
47
        lodsb
47
        lodsb
48
        test    al, al
48
        test    al, al
49
        jz      @f
49
        jz      @f
50
        stosb
50
        stosb
51
        jmp     @r
51
        jmp     @r
52
  @@:
52
  @@:
53
}
53
}
54
 
54
 
55
macro HTTP_init_buffer buffer, socketnum {
55
macro HTTP_init_buffer buffer, socketnum {
56
 
56
 
57
        mov     eax, buffer
57
        mov     eax, buffer
58
        push    socketnum
58
        push    socketnum
59
        popd    [eax + http_msg.socket]
59
        popd    [eax + http_msg.socket]
60
        lea     esi, [eax + http_msg.data]
60
        lea     esi, [eax + http_msg.data]
61
        mov     [eax + http_msg.flags], FLAG_CONNECTED
61
        mov     [eax + http_msg.flags], FLAG_CONNECTED
62
        mov     [eax + http_msg.write_ptr], esi
62
        mov     [eax + http_msg.write_ptr], esi
63
        mov     [eax + http_msg.buffer_length], BUFFERSIZE -  http_msg.data
63
        mov     [eax + http_msg.buffer_length], BUFFERSIZE -  http_msg.data
64
        mov     [eax + http_msg.chunk_ptr], 0
64
        mov     [eax + http_msg.chunk_ptr], 0
65
 
65
 
66
        mov     [eax + http_msg.status], 0
66
        mov     [eax + http_msg.status], 0
67
        mov     [eax + http_msg.header_length], 0
67
        mov     [eax + http_msg.header_length], 0
68
        mov     [eax + http_msg.content_length], 0
68
        mov     [eax + http_msg.content_length], 0
69
        mov     [eax + http_msg.content_received], 0
69
        mov     [eax + http_msg.content_received], 0
70
 
70
 
71
        push    eax ebp
71
        push    eax ebp
72
        mov     ebp, eax
72
        mov     ebp, eax
73
        mcall   29, 9
73
        mcall   29, 9
74
        mov     [ebp + http_msg.timestamp], eax
74
        mov     [ebp + http_msg.timestamp], eax
75
        pop     ebp eax
75
        pop     ebp eax
76
}
76
}
77
 
77
 
78
section '.flat' code readable align 16
78
section '.flat' code readable align 16
79
 
79
 
80
;;===========================================================================;;
80
;;===========================================================================;;
81
lib_init: ;//////////////////////////////////////////////////////////////////;;
81
lib_init: ;//////////////////////////////////////////////////////////////////;;
82
;;---------------------------------------------------------------------------;;
82
;;---------------------------------------------------------------------------;;
83
;? Library entry point (called after library load)                           ;;
83
;? Library entry point (called after library load)                           ;;
84
;;---------------------------------------------------------------------------;;
84
;;---------------------------------------------------------------------------;;
85
;> eax = pointer to memory allocation routine                                ;;
85
;> eax = pointer to memory allocation routine                                ;;
86
;> ebx = pointer to memory freeing routine                                   ;;
86
;> ebx = pointer to memory freeing routine                                   ;;
87
;> ecx = pointer to memory reallocation routine                              ;;
87
;> ecx = pointer to memory reallocation routine                              ;;
88
;> edx = pointer to library loading routine                                  ;;
88
;> edx = pointer to library loading routine                                  ;;
89
;;---------------------------------------------------------------------------;;
89
;;---------------------------------------------------------------------------;;
90
;< eax = 1 (fail) / 0 (ok) (library initialization result)                   ;;
90
;< eax = 1 (fail) / 0 (ok) (library initialization result)                   ;;
91
;;===========================================================================;;
91
;;===========================================================================;;
92
        mov     [mem.alloc], eax
92
        mov     [mem.alloc], eax
93
        mov     [mem.free], ebx
93
        mov     [mem.free], ebx
94
        mov     [mem.realloc], ecx
94
        mov     [mem.realloc], ecx
95
        mov     [dll.load], edx
95
        mov     [dll.load], edx
96
 
96
 
97
        invoke  dll.load, @IMPORT
97
        invoke  dll.load, @IMPORT
98
        or      eax, eax
98
        or      eax, eax
99
        jz      .ok
99
        jz      .ok
100
 
100
 
101
; load proxy settings
101
; load proxy settings
102
        invoke  ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr
102
        invoke  ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr
103
        invoke  ini.get_int, inifile, sec_proxy, key_proxyport, 80
103
        invoke  ini.get_int, inifile, sec_proxy, key_proxyport, 80
104
        mov     [proxyPort], eax
104
        mov     [proxyPort], eax
105
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
105
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
106
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
106
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
107
 
107
 
108
        xor     eax, eax
108
        xor     eax, eax
109
        inc     eax
109
        inc     eax
110
        ret
110
        ret
111
 
111
 
112
  .ok:
112
  .ok:
113
        xor     eax, eax
113
        xor     eax, eax
114
        ret
114
        ret
115
 
115
 
116
 
116
 
117
 
117
 
118
 
118
 
119
 
119
 
120
;;================================================================================================;;
120
;;================================================================================================;;
121
proc HTTP_get URL ;///////////////////////////////////////////////////////////////////////////////;;
121
proc HTTP_get URL ;///////////////////////////////////////////////////////////////////////////////;;
122
;;------------------------------------------------------------------------------------------------;;
122
;;------------------------------------------------------------------------------------------------;;
123
;? Initiates a HTTP connection, using 'GET' method.                                               ;;
123
;? Initiates a HTTP connection, using 'GET' method.                                               ;;
124
;;------------------------------------------------------------------------------------------------;;
124
;;------------------------------------------------------------------------------------------------;;
125
;> URL = pointer to ASCIIZ URL                                                                    ;;
125
;> URL = pointer to ASCIIZ URL                                                                    ;;
126
;;------------------------------------------------------------------------------------------------;;
126
;;------------------------------------------------------------------------------------------------;;
127
;< eax = 0 (error) / buffer ptr                                                                   ;;
127
;< eax = 0 (error) / buffer ptr                                                                   ;;
128
;;================================================================================================;;
128
;;================================================================================================;;
129
locals
129
locals
130
        hostname        dd ?
130
        hostname        dd ?
131
        pageaddr        dd ?
131
        pageaddr        dd ?
132
        sockaddr        dd ?
132
        sockaddr        dd ?
133
        socketnum       dd ?
133
        socketnum       dd ?
134
        buffer          dd ?
134
        buffer          dd ?
135
        port            dd ?
135
        port            dd ?
136
endl
136
endl
137
 
137
 
138
; split the URL into hostname and pageaddr
138
; split the URL into hostname and pageaddr
139
        stdcall parse_url, [URL]
139
        stdcall parse_url, [URL]
140
        test    eax, eax
140
        test    eax, eax
141
        jz      .error
141
        jz      .error
142
        mov     [hostname], eax
142
        mov     [hostname], eax
143
        mov     [pageaddr], ebx
143
        mov     [pageaddr], ebx
144
 
144
 
145
; Do we need to use a proxy?
145
; Do we need to use a proxy?
146
        cmp     [proxyAddr], 0
146
        cmp     [proxyAddr], 0
147
        jne     .proxy_done
147
        jne     .proxy_done
148
 
148
 
149
  .proxy_done:
149
  .proxy_done:
150
 
150
 
151
;;;;
151
;;;;
152
        mov     [port], 80      ;;;; FIXME
152
        mov     [port], 80      ;;;; FIXME
153
 
153
 
154
; Connect to the other side.
154
; Connect to the other side.
155
        stdcall open_connection, [hostname], [port]
155
        stdcall open_connection, [hostname], [port]
156
        test    eax, eax
156
        test    eax, eax
157
        jz      .error
157
        jz      .error
158
        mov     [socketnum], eax
158
        mov     [socketnum], eax
159
 
159
 
160
; Create the HTTP request.
160
; Create the HTTP request.
161
        invoke  mem.alloc, BUFFERSIZE
161
        invoke  mem.alloc, BUFFERSIZE
162
        test    eax, eax
162
        test    eax, eax
163
        jz      .error
163
        jz      .error
164
        mov     [buffer], eax
164
        mov     [buffer], eax
165
        mov     edi, eax
165
        mov     edi, eax
166
        DEBUGF  1, "Buffer has been allocated.\n"
166
        DEBUGF  1, "Buffer has been allocated.\n"
167
 
167
 
168
        mov     esi, str_get
168
        mov     esi, str_get
169
        copy_till_zero
169
        copy_till_zero
170
 
170
 
171
        mov     esi, [pageaddr]
171
        mov     esi, [pageaddr]
172
        copy_till_zero
172
        copy_till_zero
173
 
173
 
174
        mov     esi, str_http11
174
        mov     esi, str_http11
175
        mov     ecx, str_http11.length
175
        mov     ecx, str_http11.length
176
        rep     movsb
176
        rep     movsb
177
 
177
 
178
        mov     esi, [hostname]
178
        mov     esi, [hostname]
179
        copy_till_zero
179
        copy_till_zero
180
 
180
 
181
        mov     esi, str_close
181
        mov     esi, str_close
182
        mov     ecx, str_close.length
182
        mov     ecx, str_close.length
183
        rep     movsb
183
        rep     movsb
184
 
184
 
185
        mov     byte[edi], 0
185
        mov     byte[edi], 0
186
        DEBUGF  1, "Request:\n%s", [buffer]
186
        DEBUGF  1, "Request:\n%s", [buffer]
187
 
187
 
188
; Send the request
188
; Send the request
189
        mov     esi, edi
189
        mov     esi, edi
190
        sub     esi, [buffer]   ; length
190
        sub     esi, [buffer]   ; length
191
        xor     edi, edi        ; flags
191
        xor     edi, edi        ; flags
192
 
192
 
193
        mcall   send, [socketnum], [buffer]
193
        mcall   send, [socketnum], [buffer]
194
        test    eax, eax
194
        test    eax, eax
195
        jz      .error
195
        jz      .error
196
        DEBUGF  1, "Request has been sent to server.\n"
196
        DEBUGF  1, "Request has been sent to server.\n"
197
 
197
 
198
        HTTP_init_buffer [buffer], [socketnum]
198
        HTTP_init_buffer [buffer], [socketnum]
199
 
199
 
200
        ret                     ; return buffer ptr
200
        ret                     ; return buffer ptr
201
 
201
 
202
  .error:
202
  .error:
203
        DEBUGF  1, "Error!\n"
203
        DEBUGF  1, "Error!\n"
204
        xor     eax, eax        ; return 0 = error
204
        xor     eax, eax        ; return 0 = error
205
        ret
205
        ret
206
 
206
 
207
endp
207
endp
208
 
208
 
209
 
209
 
210
 
210
 
211
;;================================================================================================;;
211
;;================================================================================================;;
212
proc HTTP_head URL ;//////////////////////////////////////////////////////////////////////////////;;
212
proc HTTP_head URL ;//////////////////////////////////////////////////////////////////////////////;;
213
;;------------------------------------------------------------------------------------------------;;
213
;;------------------------------------------------------------------------------------------------;;
214
;? Initiates a HTTP connection, using 'HEAD' method.                                              ;;
214
;? Initiates a HTTP connection, using 'HEAD' method.                                              ;;
215
;;------------------------------------------------------------------------------------------------;;
215
;;------------------------------------------------------------------------------------------------;;
216
;> URL = pointer to ASCIIZ URL                                                                    ;;
216
;> URL = pointer to ASCIIZ URL                                                                    ;;
217
;;------------------------------------------------------------------------------------------------;;
217
;;------------------------------------------------------------------------------------------------;;
218
;< eax = 0 (error) / buffer ptr                                                                   ;;
218
;< eax = 0 (error) / buffer ptr                                                                   ;;
219
;;================================================================================================;;
219
;;================================================================================================;;
220
locals
220
locals
221
        hostname        dd ?
221
        hostname        dd ?
222
        pageaddr        dd ?
222
        pageaddr        dd ?
223
        sockaddr        dd ?
223
        sockaddr        dd ?
224
        socketnum       dd ?
224
        socketnum       dd ?
225
        buffer          dd ?
225
        buffer          dd ?
226
        port            dd ?
226
        port            dd ?
227
endl
227
endl
228
 
228
 
229
; split the URL into hostname and pageaddr
229
; split the URL into hostname and pageaddr
230
        stdcall parse_url, [URL]
230
        stdcall parse_url, [URL]
231
        test    eax, eax
231
        test    eax, eax
232
        jz      .error
232
        jz      .error
233
        mov     [hostname], eax
233
        mov     [hostname], eax
234
        mov     [pageaddr], ebx
234
        mov     [pageaddr], ebx
235
 
235
 
236
; Do we need to use a proxy?
236
; Do we need to use a proxy?
237
        cmp     [proxyAddr], 0
237
        cmp     [proxyAddr], 0
238
        jne     .proxy_done
238
        jne     .proxy_done
239
 
239
 
240
        ; TODO: set hostname to that of the
240
        ; TODO: set hostname to that of the
241
  .proxy_done:
241
  .proxy_done:
242
 
242
 
243
;;;;
243
;;;;
244
        mov     [port], 80      ;;;; FIXME
244
        mov     [port], 80      ;;;; FIXME
245
 
245
 
246
; Connect to the other side.
246
; Connect to the other side.
247
        stdcall open_connection, [hostname], [port]
247
        stdcall open_connection, [hostname], [port]
248
        test    eax, eax
248
        test    eax, eax
249
        jz      .error
249
        jz      .error
250
        mov     [socketnum], eax
250
        mov     [socketnum], eax
251
 
251
 
252
; Create the HTTP request.
252
; Create the HTTP request.
253
        invoke  mem.alloc, BUFFERSIZE
253
        invoke  mem.alloc, BUFFERSIZE
254
        test    eax, eax
254
        test    eax, eax
255
        jz      .error
255
        jz      .error
256
        mov     [buffer], eax
256
        mov     [buffer], eax
257
        mov     edi, eax
257
        mov     edi, eax
258
        DEBUGF  1, "Buffer has been allocated.\n"
258
        DEBUGF  1, "Buffer has been allocated.\n"
259
 
259
 
260
        mov     esi, str_head
260
        mov     esi, str_head
261
        copy_till_zero
261
        copy_till_zero
262
 
262
 
263
        mov     esi, [pageaddr]
263
        mov     esi, [pageaddr]
264
        copy_till_zero
264
        copy_till_zero
265
 
265
 
266
        mov     esi, str_http11
266
        mov     esi, str_http11
267
        mov     ecx, str_http11.length
267
        mov     ecx, str_http11.length
268
        rep     movsb
268
        rep     movsb
269
 
269
 
270
        mov     esi, [hostname]
270
        mov     esi, [hostname]
271
        copy_till_zero
271
        copy_till_zero
272
 
272
 
273
        mov     esi, str_close
273
        mov     esi, str_close
274
        mov     ecx, str_close.length
274
        mov     ecx, str_close.length
275
        rep     movsb
275
        rep     movsb
276
 
276
 
277
        mov     byte[edi], 0
277
        mov     byte[edi], 0
278
        DEBUGF  1, "Request:\n%s", [buffer]
278
        DEBUGF  1, "Request:\n%s", [buffer]
279
 
279
 
280
; Send the request
280
; Send the request
281
        mov     esi, edi
281
        mov     esi, edi
282
        sub     esi, [buffer]   ; length
282
        sub     esi, [buffer]   ; length
283
        xor     edi, edi        ; flags
283
        xor     edi, edi        ; flags
284
 
284
 
285
        mcall   send, [socketnum], [buffer]
285
        mcall   send, [socketnum], [buffer]
286
        test    eax, eax
286
        test    eax, eax
287
        jz      .error
287
        jz      .error
288
        DEBUGF  1, "Request has been sent to server.\n"
288
        DEBUGF  1, "Request has been sent to server.\n"
289
 
289
 
290
        HTTP_init_buffer [buffer], [socketnum]
290
        HTTP_init_buffer [buffer], [socketnum]
291
 
291
 
292
        ret                     ; return buffer ptr
292
        ret                     ; return buffer ptr
293
 
293
 
294
  .error:
294
  .error:
295
        DEBUGF  1, "Error!\n"
295
        DEBUGF  1, "Error!\n"
296
        xor     eax, eax        ; return 0 = error
296
        xor     eax, eax        ; return 0 = error
297
        ret
297
        ret
298
 
298
 
299
endp
299
endp
300
 
300
 
301
 
301
 
302
;;================================================================================================;;
302
;;================================================================================================;;
303
proc HTTP_post URL, content_type, content_length ;////////////////////////////////////////////////;;
303
proc HTTP_post URL, content_type, content_length ;////////////////////////////////////////////////;;
304
;;------------------------------------------------------------------------------------------------;;
304
;;------------------------------------------------------------------------------------------------;;
305
;? Initiates a HTTP connection, using 'GET' method.                                               ;;
305
;? Initiates a HTTP connection, using 'GET' method.                                               ;;
306
;;------------------------------------------------------------------------------------------------;;
306
;;------------------------------------------------------------------------------------------------;;
307
;> URL                  = pointer to ASCIIZ URL                                                   ;;
307
;> URL                  = pointer to ASCIIZ URL                                                   ;;
308
;> content_type         = pointer to ASCIIZ string containing content type                        ;;
308
;> content_type         = pointer to ASCIIZ string containing content type                        ;;
309
;> content_length       = length of content (in bytes)                                            ;;
309
;> content_length       = length of content (in bytes)                                            ;;
310
;;------------------------------------------------------------------------------------------------;;
310
;;------------------------------------------------------------------------------------------------;;
311
;< eax = 0 (error) / buffer ptr                                                                   ;;
311
;< eax = 0 (error) / buffer ptr                                                                   ;;
312
;;================================================================================================;;
312
;;================================================================================================;;
313
locals
313
locals
314
        hostname        dd ?
314
        hostname        dd ?
315
        pageaddr        dd ?
315
        pageaddr        dd ?
316
        sockaddr        dd ?
316
        sockaddr        dd ?
317
        socketnum       dd ?
317
        socketnum       dd ?
318
        buffer          dd ?
318
        buffer          dd ?
319
        port            dd ?
319
        port            dd ?
320
endl
320
endl
321
 
321
 
322
; split the URL into hostname and pageaddr
322
; split the URL into hostname and pageaddr
323
        stdcall parse_url, [URL]
323
        stdcall parse_url, [URL]
324
        test    eax, eax
324
        test    eax, eax
325
        jz      .error
325
        jz      .error
326
        mov     [hostname], eax
326
        mov     [hostname], eax
327
        mov     [pageaddr], ebx
327
        mov     [pageaddr], ebx
328
 
328
 
329
; Do we need to use a proxy?
329
; Do we need to use a proxy?
330
        cmp     [proxyAddr], 0
330
        cmp     [proxyAddr], 0
331
        jne     .proxy_done
331
        jne     .proxy_done
332
 
332
 
333
        ; TODO: set hostname to that of the
333
        ; TODO: set hostname to that of the
334
  .proxy_done:
334
  .proxy_done:
335
 
335
 
336
;;;;
336
;;;;
337
        mov     [port], 80      ;;;; FIXME
337
        mov     [port], 80      ;;;; FIXME
338
 
338
 
339
; Connect to the other side.
339
; Connect to the other side.
340
        stdcall open_connection, [hostname], [port]
340
        stdcall open_connection, [hostname], [port]
341
        test    eax, eax
341
        test    eax, eax
342
        jz      .error
342
        jz      .error
343
        mov     [socketnum], eax
343
        mov     [socketnum], eax
344
 
344
 
345
; Create the HTTP request.
345
; Create the HTTP request.
346
        invoke  mem.alloc, BUFFERSIZE
346
        invoke  mem.alloc, BUFFERSIZE
347
        test    eax, eax
347
        test    eax, eax
348
        jz      .error
348
        jz      .error
349
        mov     [buffer], eax
349
        mov     [buffer], eax
350
        mov     edi, eax
350
        mov     edi, eax
351
        DEBUGF  1, "Buffer has been allocated.\n"
351
        DEBUGF  1, "Buffer has been allocated.\n"
352
 
352
 
353
        mov     esi, str_post
353
        mov     esi, str_post
354
        copy_till_zero
354
        copy_till_zero
355
 
355
 
356
        mov     esi, [pageaddr]
356
        mov     esi, [pageaddr]
357
        copy_till_zero
357
        copy_till_zero
358
 
358
 
359
        mov     esi, str_http11
359
        mov     esi, str_http11
360
        mov     ecx, str_http11.length
360
        mov     ecx, str_http11.length
361
        rep     movsb
361
        rep     movsb
362
 
362
 
363
        mov     esi, [hostname]
363
        mov     esi, [hostname]
364
        copy_till_zero
364
        copy_till_zero
365
 
365
 
366
        mov     esi, str_post_cl
366
        mov     esi, str_post_cl
367
        mov     ecx, str_post_cl.length
367
        mov     ecx, str_post_cl.length
368
        rep     movsb
368
        rep     movsb
369
 
369
 
370
        mov     eax, [content_length]
370
        mov     eax, [content_length]
371
        call    ascii_dec
371
        call    ascii_dec
372
 
372
 
373
        mov     esi, str_post_ct
373
        mov     esi, str_post_ct
374
        mov     ecx, str_post_ct.length
374
        mov     ecx, str_post_ct.length
375
        rep     movsb
375
        rep     movsb
376
 
376
 
377
        mov     esi, [content_type]
377
        mov     esi, [content_type]
378
        rep     movsb
378
        rep     movsb
379
 
379
 
380
        mov     esi, str_close
380
        mov     esi, str_close
381
        mov     ecx, str_close.length
381
        mov     ecx, str_close.length
382
        rep     movsb
382
        rep     movsb
383
 
383
 
384
        mov     byte[edi], 0
384
        mov     byte[edi], 0
385
        DEBUGF  1, "Request:\n%s", [buffer]
385
        DEBUGF  1, "Request:\n%s", [buffer]
386
 
386
 
387
; Send the request
387
; Send the request
388
        mov     esi, edi
388
        mov     esi, edi
389
        sub     esi, [buffer]   ; length
389
        sub     esi, [buffer]   ; length
390
        xor     edi, edi        ; flags
390
        xor     edi, edi        ; flags
391
        mcall   send, [socketnum], [buffer]
391
        mcall   send, [socketnum], [buffer]
392
        test    eax, eax
392
        test    eax, eax
393
        jz      .error
393
        jz      .error
394
        DEBUGF  1, "Request has been sent to server.\n"
394
        DEBUGF  1, "Request has been sent to server.\n"
395
 
395
 
396
        HTTP_init_buffer [buffer], [socketnum]
396
        HTTP_init_buffer [buffer], [socketnum]
397
 
397
 
398
;        mov     eax, [buffer]
398
;        mov     eax, [buffer]
399
 
399
 
400
        ret                     ; return buffer ptr
400
        ret                     ; return buffer ptr
401
 
401
 
402
  .error:
402
  .error:
403
        DEBUGF  1, "Error!\n"
403
        DEBUGF  1, "Error!\n"
404
        xor     eax, eax        ; return 0 = error
404
        xor     eax, eax        ; return 0 = error
405
        ret
405
        ret
406
 
406
 
407
endp
407
endp
408
 
408
 
409
 
409
 
410
 
410
 
411
;;================================================================================================;;
411
;;================================================================================================;;
412
proc HTTP_process identifier ;////////////////////////////////////////////////////////////////////;;
412
proc HTTP_process identifier ;////////////////////////////////////////////////////////////////////;;
413
;;------------------------------------------------------------------------------------------------;;
413
;;------------------------------------------------------------------------------------------------;;
414
;? Receive data from the server, parse headers and put data in receive buffer.                    ;;
414
;? Receive data from the server, parse headers and put data in receive buffer.                    ;;
415
;? To complete a transfer, this procedure must be called over and over again untill it returns 0. ;;
415
;? To complete a transfer, this procedure must be called over and over again untill it returns 0. ;;
416
;;------------------------------------------------------------------------------------------------;;
416
;;------------------------------------------------------------------------------------------------;;
417
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
417
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
418
;;------------------------------------------------------------------------------------------------;;
418
;;------------------------------------------------------------------------------------------------;;
419
;< eax = -1 (not finished) / 0 finished                                                           ;;
419
;< eax = -1 (not finished) / 0 finished                                                           ;;
420
;;================================================================================================;;
420
;;================================================================================================;;
421
        pusha
421
        pusha
422
        mov     ebp, [identifier]
422
        mov     ebp, [identifier]
423
 
423
 
424
        test    [ebp + http_msg.flags], FLAG_CONNECTED
424
        test    [ebp + http_msg.flags], FLAG_CONNECTED
425
        jz      .connection_closed
425
        jz      .connection_closed
426
 
426
 
427
; Receive some data
427
; Receive some data
428
        mcall   recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
428
        mcall   recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
429
                      [ebp + http_msg.buffer_length], MSG_DONTWAIT
429
                      [ebp + http_msg.buffer_length], MSG_DONTWAIT
430
        cmp     eax, 0xffffffff
430
        cmp     eax, 0xffffffff
431
        je      .check_socket
431
        je      .check_socket
432
        DEBUGF  1, "Received %u bytes\n", eax
432
        DEBUGF  1, "Received %u bytes\n", eax
433
 
433
 
434
        push    eax
434
        push    eax
435
        mcall   29, 9
435
        mcall   29, 9
436
        mov     [ebp + http_msg.timestamp], eax
436
        mov     [ebp + http_msg.timestamp], eax
437
        pop     eax
437
        pop     eax
438
 
438
 
439
; Update pointers
439
; Update pointers
440
        mov     edi, [ebp + http_msg.write_ptr]
440
        mov     edi, [ebp + http_msg.write_ptr]
441
        add     [ebp + http_msg.write_ptr], eax
441
        add     [ebp + http_msg.write_ptr], eax
442
        sub     [ebp + http_msg.buffer_length], eax
442
        sub     [ebp + http_msg.buffer_length], eax
443
        jz      .got_all_data
443
        jz      .got_all_data
444
 
444
 
445
; If data is chunked, combine chunks into contiguous data.
445
; If data is chunked, combine chunks into contiguous data.
446
        test    [ebp + http_msg.flags], FLAG_CHUNKED
446
        test    [ebp + http_msg.flags], FLAG_CHUNKED
447
        jnz     .chunk_loop
447
        jnz     .chunk_loop
448
 
448
 
449
; Did we detect the header yet?
449
; Did we detect the header yet?
450
        test    [ebp + http_msg.flags], FLAG_GOT_HEADER
450
        test    [ebp + http_msg.flags], FLAG_GOT_HEADER
451
        jnz     .header_parsed
451
        jnz     .header_parsed
452
 
452
 
453
        push    eax
453
        push    eax
454
 
454
 
455
; We havent found the header yet, search for it..
455
; We havent found the header yet, search for it..
456
        sub     eax, 4
456
        sub     eax, 4
457
        jl      .need_more_data_pop
457
        jl      .need_more_data_pop
458
        inc     eax
458
        inc     eax
459
  .scan:
459
  .scan:
460
        ; scan for end of header (empty line)
460
        ; scan for end of header (empty line)
461
        cmp     dword[edi], 0x0a0d0a0d                  ; end of header
461
        cmp     dword[edi], 0x0a0d0a0d                  ; end of header
462
        je      .end_of_header
462
        je      .end_of_header
463
        cmp     word[edi+2], 0x0a0a
463
        cmp     word[edi+2], 0x0a0a
464
        je      .end_of_header
464
        je      .end_of_header
465
        inc     edi
465
        inc     edi
466
        dec     eax
466
        dec     eax
467
        jnz     .scan
467
        jnz     .scan
468
        jmp     .need_more_data_pop
468
        jmp     .need_more_data_pop
469
 
469
 
470
  .end_of_header:
470
  .end_of_header:
471
        add     edi, 4 - http_msg.data
471
        add     edi, 4 - http_msg.data
472
        sub     edi, ebp
472
        sub     edi, ebp
473
        mov     [ebp + http_msg.header_length], edi
473
        mov     [ebp + http_msg.header_length], edi
474
        or      [ebp + http_msg.flags], FLAG_GOT_HEADER
474
        or      [ebp + http_msg.flags], FLAG_GOT_HEADER
475
        DEBUGF  1, "Header length: %u\n", edi
475
        DEBUGF  1, "Header length: %u\n", edi
476
 
476
 
477
; Ok, we have found header:
477
; Ok, we have found header:
478
        cmp     dword[ebp + http_msg.data], 'HTTP'
478
        cmp     dword[ebp + http_msg.data], 'HTTP'
479
        jne     .invalid_header
479
        jne     .invalid_header
480
        cmp     dword[ebp + http_msg.data+4], '/1.0'
480
        cmp     dword[ebp + http_msg.data+4], '/1.0'
481
        je      .http_1.0
481
        je      .http_1.0
482
        cmp     dword[ebp + http_msg.data+4], '/1.1'
482
        cmp     dword[ebp + http_msg.data+4], '/1.1'
483
        jne     .invalid_header
483
        jne     .invalid_header
484
        or      [ebp + http_msg.flags], FLAG_HTTP11
484
        or      [ebp + http_msg.flags], FLAG_HTTP11
485
  .http_1.0:
485
  .http_1.0:
486
        cmp     byte[ebp + http_msg.data+8], ' '
486
        cmp     byte[ebp + http_msg.data+8], ' '
487
        jne     .invalid_header
487
        jne     .invalid_header
488
        DEBUGF  1, "Header seems valid.\n"
488
        DEBUGF  1, "Header seems valid.\n"
489
 
489
 
490
        lea     esi, [ebp + http_msg.data+9]
490
        lea     esi, [ebp + http_msg.data+9]
491
        xor     eax, eax
491
        xor     eax, eax
492
        xor     ebx, ebx
492
        xor     ebx, ebx
493
        mov     ecx, 3
493
        mov     ecx, 3
494
  .statusloop:
494
  .statusloop:
495
        lodsb
495
        lodsb
496
        sub     al, '0'
496
        sub     al, '0'
497
        jb      .invalid_header
497
        jb      .invalid_header
498
        cmp     al, 9
498
        cmp     al, 9
499
        ja      .invalid_header
499
        ja      .invalid_header
500
        lea     ebx, [ebx + 4*ebx]
500
        lea     ebx, [ebx + 4*ebx]
501
        shl     ebx, 1
501
        shl     ebx, 1
502
        add     ebx, eax
502
        add     ebx, eax
503
        dec     ecx
503
        dec     ecx
504
        jnz     .statusloop
504
        jnz     .statusloop
505
        mov     [ebp + http_msg.status], ebx
505
        mov     [ebp + http_msg.status], ebx
506
        DEBUGF  1, "Status: %u\n", ebx
506
        DEBUGF  1, "Status: %u\n", ebx
507
 
507
 
508
; Now, convert all header names to lowercase.
508
; Now, convert all header names to lowercase.
509
; This way, it will be much easier to find certain header fields, later on.
509
; This way, it will be much easier to find certain header fields, later on.
510
 
510
 
511
        lea     esi, [ebp + http_msg.data]
511
        lea     esi, [ebp + http_msg.data]
512
        mov     ecx, [ebp + http_msg.header_length]
512
        mov     ecx, [ebp + http_msg.header_length]
513
  .need_newline:
513
  .need_newline:
514
        inc     esi
514
        inc     esi
515
        dec     ecx
515
        dec     ecx
516
        jz      .convert_done
516
        jz      .convert_done
517
        cmp     byte[esi], 10
517
        cmp     byte[esi], 10
518
        jne     .need_newline
518
        jne     .need_newline
519
; Ok, we have a newline, a line beginning with space or tabs has no header fields.
519
; Ok, we have a newline, a line beginning with space or tabs has no header fields.
520
 
520
 
521
        inc     esi
521
        inc     esi
522
        dec     ecx
522
        dec     ecx
523
        jz      .convert_done
523
        jz      .convert_done
524
        cmp     byte[esi], ' '
524
        cmp     byte[esi], ' '
525
        je      .need_newline
525
        je      .need_newline
526
        cmp     byte[esi], 9    ; horizontal tab
526
        cmp     byte[esi], 9    ; horizontal tab
527
        je      .need_newline
527
        je      .need_newline
528
        jmp     .convert_loop
528
        jmp     .convert_loop
529
  .next_char:
529
  .next_char:
530
        inc     esi
530
        inc     esi
531
        dec     ecx
531
        dec     ecx
532
        jz      .convert_done
532
        jz      .convert_done
533
  .convert_loop:
533
  .convert_loop:
534
        cmp     byte[esi], ':'
534
        cmp     byte[esi], ':'
535
        je      .need_newline
535
        je      .need_newline
536
        cmp     byte[esi], 'A'
536
        cmp     byte[esi], 'A'
537
        jb      .next_char
537
        jb      .next_char
538
        cmp     byte[esi], 'Z'
538
        cmp     byte[esi], 'Z'
539
        ja      .next_char
539
        ja      .next_char
540
        or      byte[esi], 0x20 ; convert to lowercase
540
        or      byte[esi], 0x20 ; convert to lowercase
541
        jmp     .next_char
541
        jmp     .next_char
542
  .convert_done:
542
  .convert_done:
543
        mov     byte[esi-1], 0
543
        mov     byte[esi-1], 0
544
        lea     esi, [ebp + http_msg.data]
544
        lea     esi, [ebp + http_msg.data]
545
        DEBUGF  1, "Header names converted to lowercase:\n%s\n", esi
545
        DEBUGF  1, "Header names converted to lowercase:\n%s\n", esi
546
 
546
 
547
; Check for content-length header field.
547
; Check for content-length header field.
548
        stdcall find_header_field, ebp, str_cl
548
        stdcall find_header_field, ebp, str_cl
549
        test    eax, eax
549
        test    eax, eax
550
        jz      .no_content
550
        jz      .no_content
551
        or      [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
551
        or      [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
552
 
552
 
553
        xor     edx, edx
553
        xor     edx, edx
554
  .cl_loop:
554
  .cl_loop:
555
        movzx   ebx, byte[eax]
555
        movzx   ebx, byte[eax]
556
        inc     eax
556
        inc     eax
557
        cmp     bl, 10
557
        cmp     bl, 10
558
        je      .cl_ok
558
        je      .cl_ok
559
        cmp     bl, 13
559
        cmp     bl, 13
560
        je      .cl_ok
560
        je      .cl_ok
561
        cmp     bl, ' '
561
        cmp     bl, ' '
562
        je      .cl_ok
562
        je      .cl_ok
563
        sub     bl, '0'
563
        sub     bl, '0'
564
        jb      .invalid_header
564
        jb      .invalid_header
565
        cmp     bl, 9
565
        cmp     bl, 9
566
        ja      .invalid_header
566
        ja      .invalid_header
567
        lea     edx, [edx + edx*4]      ; edx = edx*10
567
        lea     edx, [edx + edx*4]      ; edx = edx*10
568
        shl     edx, 1                  ;
568
        shl     edx, 1                  ;
569
        add     edx, ebx
569
        add     edx, ebx
570
        jmp     .cl_loop
570
        jmp     .cl_loop
571
 
571
 
572
  .cl_ok:
572
  .cl_ok:
573
        mov     [ebp + http_msg.content_length], edx
573
        mov     [ebp + http_msg.content_length], edx
574
        DEBUGF  1, "Content-length: %u\n", edx
574
        DEBUGF  1, "Content-length: %u\n", edx
575
 
575
 
576
; Resize buffer according to content-length.
576
; Resize buffer according to content-length.
577
        add     edx, [ebp + http_msg.header_length]
577
        add     edx, [ebp + http_msg.header_length]
578
        add     edx, http_msg.data
578
        add     edx, http_msg.data
579
 
579
 
580
        mov     ecx, edx
580
        mov     ecx, edx
581
        sub     ecx, [ebp + http_msg.write_ptr]
581
        sub     ecx, [ebp + http_msg.write_ptr]
582
        mov     [ebp + http_msg.buffer_length], ecx
582
        mov     [ebp + http_msg.buffer_length], ecx
583
 
583
 
584
        invoke  mem.realloc, ebp, edx
584
        invoke  mem.realloc, ebp, edx
585
        or      eax, eax
585
        or      eax, eax
586
        jz      .no_ram_pop
586
        jz      .no_ram_pop
587
 
587
 
588
        pop     eax
588
        pop     eax
589
        sub     eax, [ebp + http_msg.header_length]
589
        sub     eax, [ebp + http_msg.header_length]
590
        jmp     .header_parsed  ; hooray!
590
        jmp     .header_parsed  ; hooray!
591
 
591
 
592
  .no_content:
592
  .no_content:
593
        DEBUGF  1, "Content-length not found.\n"
593
        DEBUGF  1, "Content-length not found.\n"
594
 
594
 
595
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
595
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
596
; Try to find 'transfer-encoding' header.
596
; Try to find 'transfer-encoding' header.
597
        stdcall find_header_field, ebp, str_te
597
        stdcall find_header_field, ebp, str_te
598
        test    eax, eax
598
        test    eax, eax
599
        jz      .invalid_header
599
        jz      .invalid_header
600
 
600
 
601
        mov     ebx, dword[eax]
601
        mov     ebx, dword[eax]
602
        or      ebx, 0x20202020
602
        or      ebx, 0x20202020
603
        cmp     ebx, 'chun'
603
        cmp     ebx, 'chun'
604
        jne     .invalid_header
604
        jne     .invalid_header
605
        mov     ebx, dword[eax+4]
605
        mov     ebx, dword[eax+4]
606
        or      ebx, 0x00202020
606
        or      ebx, 0x00202020
607
        and     ebx, 0x00ffffff
607
        and     ebx, 0x00ffffff
608
        cmp     ebx, 'ked'
608
        cmp     ebx, 'ked'
609
        jne     .invalid_header
609
        jne     .invalid_header
610
 
610
 
611
        or      [ebp + http_msg.flags], FLAG_CHUNKED
611
        or      [ebp + http_msg.flags], FLAG_CHUNKED
612
        DEBUGF  1, "Transfer type is: chunked\n"
612
        DEBUGF  1, "Transfer type is: chunked\n"
613
 
613
 
614
        pop     eax
614
        pop     eax
615
 
615
 
616
; Set chunk pointer where first chunk should begin.
616
; Set chunk pointer where first chunk should begin.
617
        lea     eax, [ebp + http_msg.data]
617
        lea     eax, [ebp + http_msg.data]
618
        add     eax, [ebp + http_msg.header_length]
618
        add     eax, [ebp + http_msg.header_length]
619
        mov     [ebp + http_msg.chunk_ptr], eax
619
        mov     [ebp + http_msg.chunk_ptr], eax
620
 
620
 
621
  .chunk_loop:
621
  .chunk_loop:
622
        mov     ecx, [ebp + http_msg.write_ptr]
622
        mov     ecx, [ebp + http_msg.write_ptr]
623
        sub     ecx, [ebp + http_msg.chunk_ptr]
623
        sub     ecx, [ebp + http_msg.chunk_ptr]
624
        jb      .need_more_data_chunked         ; TODO: use this ecx !!!
624
        jb      .need_more_data_chunked         ; TODO: use this ecx !!!
625
 
625
 
626
; Chunkline starts here, convert the ASCII hex number into ebx
626
; Chunkline starts here, convert the ASCII hex number into ebx
627
        mov     esi, [ebp + http_msg.chunk_ptr]
627
        mov     esi, [ebp + http_msg.chunk_ptr]
628
        xor     ebx, ebx
628
        xor     ebx, ebx
629
  .chunk_hexloop:
629
  .chunk_hexloop:
630
        lodsb
630
        lodsb
631
        sub     al, '0'
631
        sub     al, '0'
632
        jb      .chunk_
632
        jb      .chunk_
633
        cmp     al, 9
633
        cmp     al, 9
634
        jbe     .chunk_hex
634
        jbe     .chunk_hex
635
        sub     al, 'A' - '0' - 10
635
        sub     al, 'A' - '0' - 10
636
        jb      .chunk_
636
        jb      .chunk_
637
        cmp     al, 15
637
        cmp     al, 15
638
        jbe     .chunk_hex
638
        jbe     .chunk_hex
639
        sub     al, 'a' - 'A'
639
        sub     al, 'a' - 'A'
640
        cmp     al, 15
640
        cmp     al, 15
641
        ja      .chunk_
641
        ja      .chunk_
642
  .chunk_hex:
642
  .chunk_hex:
643
        shl     ebx, 4
643
        shl     ebx, 4
644
        add     bl, al
644
        add     bl, al
645
        jmp     .chunk_hexloop
645
        jmp     .chunk_hexloop
646
  .chunk_:
646
  .chunk_:
647
        DEBUGF  1, "got chunk of %u bytes\n", ebx
647
        DEBUGF  1, "got chunk of %u bytes\n", ebx
648
;;        cmp     esi, [ebp + http_msg.chunk_ptr]
648
;;        cmp     esi, [ebp + http_msg.chunk_ptr]
649
;;        je
649
;;        je
650
; If chunk size is 0, all chunks have been received.
650
; If chunk size is 0, all chunks have been received.
651
        test    ebx, ebx
651
        test    ebx, ebx
652
        jz      .got_all_data_chunked           ; last chunk, hooray! FIXME: what if it wasnt a valid hex number???
652
        jz      .got_all_data_chunked           ; last chunk, hooray! FIXME: what if it wasnt a valid hex number???
653
 
653
 
654
; Chunkline ends with a CR, LF or simply LF
654
; Chunkline ends with a CR, LF or simply LF
655
  .end_of_chunkline?:
655
  .end_of_chunkline?:
656
        cmp     al, 10
656
        cmp     al, 10
657
        je      .end_of_chunkline
657
        je      .end_of_chunkline
658
        lodsb
658
        lodsb
659
        cmp     edi, [ebp + http_msg.write_ptr]
659
        cmp     edi, [ebp + http_msg.write_ptr]
660
        jb      .end_of_chunkline?
660
        jb      .end_of_chunkline?
661
        jmp     .need_more_data
661
        jmp     .need_more_data
662
 
662
 
663
  .end_of_chunkline:
663
  .end_of_chunkline:
664
; Update chunk ptr, and remember old one
664
; Update chunk ptr, and remember old one
665
        mov     edi, [ebp + http_msg.chunk_ptr]
665
        mov     edi, [ebp + http_msg.chunk_ptr]
666
        add     [ebp + http_msg.chunk_ptr], ebx
666
        add     [ebp + http_msg.chunk_ptr], ebx
667
; Realloc buffer, make it 'chunksize' bigger.
667
; Realloc buffer, make it 'chunksize' bigger.
668
        mov     eax, [ebp + http_msg.buffer_length]
668
        mov     eax, [ebp + http_msg.buffer_length]
669
        add     eax, ebx
669
        add     eax, ebx
670
        invoke  mem.realloc, ebp, eax
670
        invoke  mem.realloc, ebp, eax
671
        or      eax, eax
671
        or      eax, eax
672
        jz      .no_ram
672
        jz      .no_ram
673
        add     [ebp + http_msg.buffer_length], ebx
673
        add     [ebp + http_msg.buffer_length], ebx
674
 
674
 
675
; Update write ptr
675
; Update write ptr
676
        mov     eax, esi
676
        mov     eax, esi
677
        sub     eax, edi
677
        sub     eax, edi
678
        sub     [ebp + http_msg.write_ptr], eax
678
        sub     [ebp + http_msg.write_ptr], eax
679
 
679
 
680
; Now move all received data to the left (remove chunk header).
680
; Now move all received data to the left (remove chunk header).
681
; Update content_length accordingly.
681
; Update content_length accordingly.
682
        mov     ecx, [ebp + http_msg.write_ptr]
682
        mov     ecx, [ebp + http_msg.write_ptr]
683
        sub     ecx, esi
683
        sub     ecx, esi
684
        add     [ebp + http_msg.content_received], ecx
684
        add     [ebp + http_msg.content_received], ecx
685
        rep     movsb
685
        rep     movsb
686
        jmp     .chunk_loop
686
        jmp     .chunk_loop
687
 
687
 
688
; Check if we got all the data.
688
; Check if we got all the data.
689
  .header_parsed:
689
  .header_parsed:
690
        add     [ebp + http_msg.content_received], eax
690
        add     [ebp + http_msg.content_received], eax
691
        mov     eax, [ebp + http_msg.content_length]
691
        mov     eax, [ebp + http_msg.content_length]
692
        cmp     eax, [ebp + http_msg.content_received]
692
        cmp     eax, [ebp + http_msg.content_received]
693
        jae     .got_all_data
693
        jae     .got_all_data
694
        jmp     .need_more_data
694
        jmp     .need_more_data
695
  .need_more_data_pop:
695
  .need_more_data_pop:
696
        pop     eax
696
        pop     eax
697
  .need_more_data:
697
  .need_more_data:
698
        popa
698
        popa
699
        xor     eax, eax
699
        xor     eax, eax
700
        dec     eax
700
        dec     eax
701
        ret
701
        ret
702
 
702
 
703
  .need_more_data_chunked:
703
  .need_more_data_chunked:
704
        add     [ebp + http_msg.content_received], eax
704
        add     [ebp + http_msg.content_received], eax
705
        popa
705
        popa
706
        xor     eax, eax
706
        xor     eax, eax
707
        dec     eax
707
        dec     eax
708
        ret
708
        ret
709
 
709
 
710
  .got_all_data_chunked:
710
  .got_all_data_chunked:
711
        mov     eax, [ebp + http_msg.chunk_ptr]
711
        mov     eax, [ebp + http_msg.chunk_ptr]
712
        sub     eax, [ebp + http_msg.header_length]
712
        sub     eax, [ebp + http_msg.header_length]
713
        sub     eax, http_msg.data
713
        sub     eax, http_msg.data
714
        sub     eax, ebp
714
        sub     eax, ebp
715
        mov     [ebp + http_msg.content_length], eax
715
        mov     [ebp + http_msg.content_length], eax
716
        mov     [ebp + http_msg.content_received], eax
716
        mov     [ebp + http_msg.content_received], eax
717
  .got_all_data:
717
  .got_all_data:
718
        DEBUGF  1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_length]
718
        DEBUGF  1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_length]
719
        or      [ebp + http_msg.flags], FLAG_GOT_ALL_DATA
719
        or      [ebp + http_msg.flags], FLAG_GOT_ALL_DATA
720
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
720
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
721
        mcall   close, [ebp + http_msg.socket]
721
        mcall   close, [ebp + http_msg.socket]
722
        popa
722
        popa
723
        xor     eax, eax
723
        xor     eax, eax
724
        ret
724
        ret
725
 
725
 
726
  .check_socket:
726
  .check_socket:
727
        cmp     ebx, EWOULDBLOCK
727
        cmp     ebx, EWOULDBLOCK
728
        jne     .socket_error
728
        jne     .socket_error
729
 
729
 
730
        mcall   29, 9
730
        mcall   29, 9
731
        sub     eax, TIMEOUT
731
        sub     eax, TIMEOUT
732
        cmp     eax, [ebp + http_msg.timestamp]
732
        cmp     eax, [ebp + http_msg.timestamp]
733
        ja      .need_more_data
733
        jb      .need_more_data
734
        DEBUGF  1, "ERROR: timeout\n"
734
        DEBUGF  1, "ERROR: timeout\n"
735
        or      [ebp + http_msg.flags], FLAG_TIMEOUT_ERROR
735
        or      [ebp + http_msg.flags], FLAG_TIMEOUT_ERROR
736
        jmp     .disconnect
736
        jmp     .disconnect
737
 
737
 
738
  .invalid_header:
738
  .invalid_header:
739
        pop     eax
739
        pop     eax
740
        DEBUGF  1, "ERROR: invalid header\n"
740
        DEBUGF  1, "ERROR: invalid header\n"
741
        or      [ebp + http_msg.flags], FLAG_INVALID_HEADER
741
        or      [ebp + http_msg.flags], FLAG_INVALID_HEADER
742
        jmp     .disconnect
742
        jmp     .disconnect
743
 
743
 
744
  .no_ram_pop:
744
  .no_ram_pop:
745
        pop     eax
745
        pop     eax
746
  .no_ram:
746
  .no_ram:
747
        DEBUGF  1, "ERROR: out of RAM\n"
747
        DEBUGF  1, "ERROR: out of RAM\n"
748
        or      [ebp + http_msg.flags], FLAG_NO_RAM
748
        or      [ebp + http_msg.flags], FLAG_NO_RAM
749
        jmp     .disconnect
749
        jmp     .disconnect
750
 
750
 
751
  .socket_error:
751
  .socket_error:
752
        DEBUGF  1, "ERROR: socket error %u\n", ebx
752
        DEBUGF  1, "ERROR: socket error %u\n", ebx
753
        or      [ebp + http_msg.flags], FLAG_SOCKET_ERROR
753
        or      [ebp + http_msg.flags], FLAG_SOCKET_ERROR
754
  .disconnect:
754
  .disconnect:
755
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
755
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
756
        mcall   close, [ebp + http_msg.socket]
756
        mcall   close, [ebp + http_msg.socket]
757
  .connection_closed:
757
  .connection_closed:
758
        popa
758
        popa
759
        xor     eax, eax
759
        xor     eax, eax
760
        ret
760
        ret
761
 
761
 
762
endp
762
endp
763
 
763
 
764
 
764
 
765
 
765
 
766
 
766
 
767
;;================================================================================================;;
767
;;================================================================================================;;
768
proc HTTP_free identifier ;///////////////////////////////////////////////////////////////////////;;
768
proc HTTP_free identifier ;///////////////////////////////////////////////////////////////////////;;
769
;;------------------------------------------------------------------------------------------------;;
769
;;------------------------------------------------------------------------------------------------;;
770
;? Free the http_msg structure                                                                    ;;
770
;? Free the http_msg structure                                                                    ;;
771
;;------------------------------------------------------------------------------------------------;;
771
;;------------------------------------------------------------------------------------------------;;
772
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
772
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
773
;;------------------------------------------------------------------------------------------------;;
773
;;------------------------------------------------------------------------------------------------;;
774
;< none                                                                                           ;;
774
;< none                                                                                           ;;
775
;;================================================================================================;;
775
;;================================================================================================;;
776
 
776
 
777
        pusha
777
        pusha
778
        mov     ebp, [identifier]
778
        mov     ebp, [identifier]
779
 
779
 
780
        test    [ebp + http_msg.flags], FLAG_CONNECTED
780
        test    [ebp + http_msg.flags], FLAG_CONNECTED
781
        jz      .not_connected
781
        jz      .not_connected
782
 
782
 
783
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
783
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
784
        mcall   close, [ebp + http_msg.socket]
784
        mcall   close, [ebp + http_msg.socket]
785
 
785
 
786
  .not_connected:
786
  .not_connected:
787
        invoke  mem.free, ebp
787
        invoke  mem.free, ebp
788
 
788
 
789
        popa
789
        popa
790
        ret
790
        ret
791
 
791
 
792
endp
792
endp
793
 
793
 
794
 
794
 
795
 
795
 
796
;;================================================================================================;;
796
;;================================================================================================;;
797
proc HTTP_stop identifier ;///////////////////////////////////////////////////////////////////////;;
797
proc HTTP_stop identifier ;///////////////////////////////////////////////////////////////////////;;
798
;;------------------------------------------------------------------------------------------------;;
798
;;------------------------------------------------------------------------------------------------;;
799
;? Stops the open connection                                                                      ;;
799
;? Stops the open connection                                                                      ;;
800
;;------------------------------------------------------------------------------------------------;;
800
;;------------------------------------------------------------------------------------------------;;
801
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
801
;> identifier   = pointer to buffer containing http_msg struct.                                   ;;
802
;;------------------------------------------------------------------------------------------------;;
802
;;------------------------------------------------------------------------------------------------;;
803
;< none                                                                                           ;;
803
;< none                                                                                           ;;
804
;;================================================================================================;;
804
;;================================================================================================;;
805
 
805
 
806
        pusha
806
        pusha
807
        mov     ebp, [identifier]
807
        mov     ebp, [identifier]
808
 
808
 
809
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
809
        and     [ebp + http_msg.flags], not FLAG_CONNECTED
810
        mcall   close, [ebp + http_msg.socket]
810
        mcall   close, [ebp + http_msg.socket]
811
 
811
 
812
        popa
812
        popa
813
        ret
813
        ret
814
 
814
 
815
endp
815
endp
816
 
816
 
817
 
817
 
818
 
818
 
819
;;================================================================================================;;
819
;;================================================================================================;;
820
proc find_header_field identifier, headername ;///////////////////////////////////////////////////;;
820
proc find_header_field identifier, headername ;///////////////////////////////////////////////////;;
821
;;------------------------------------------------------------------------------------------------;;
821
;;------------------------------------------------------------------------------------------------;;
822
;? Find a header field in the received HTTP header                                                ;;
822
;? Find a header field in the received HTTP header                                                ;;
823
;;------------------------------------------------------------------------------------------------;;
823
;;------------------------------------------------------------------------------------------------;;
824
;> identifier   = ptr to http_msg struct                                                          ;;
824
;> identifier   = ptr to http_msg struct                                                          ;;
825
;> headername   = ptr to ASCIIZ string containg field you want to find (must be in lowercase)     ;;
825
;> headername   = ptr to ASCIIZ string containg field you want to find (must be in lowercase)     ;;
826
;;------------------------------------------------------------------------------------------------;;
826
;;------------------------------------------------------------------------------------------------;;
827
;< eax = 0 (error) / ptr to content of the HTTP header field                                      ;;
827
;< eax = 0 (error) / ptr to content of the HTTP header field                                      ;;
828
;;================================================================================================;;
828
;;================================================================================================;;
829
        push    ebx ecx edx esi edi
829
        push    ebx ecx edx esi edi
830
 
830
 
831
        DEBUGF  1, "Find header field: %s\n", [headername]
831
        DEBUGF  1, "Find header field: %s\n", [headername]
832
 
832
 
833
        mov     ebx, [identifier]
833
        mov     ebx, [identifier]
834
        test    [ebx + http_msg.flags], FLAG_GOT_HEADER
834
        test    [ebx + http_msg.flags], FLAG_GOT_HEADER
835
        jz      .fail
835
        jz      .fail
836
 
836
 
837
        lea     edx, [ebx + http_msg.data]
837
        lea     edx, [ebx + http_msg.data]
838
        mov     ecx, edx
838
        mov     ecx, edx
839
        add     ecx, [ebx + http_msg.header_length]
839
        add     ecx, [ebx + http_msg.header_length]
840
 
840
 
841
  .restart:
841
  .restart:
842
        mov     esi, [headername]
842
        mov     esi, [headername]
843
        mov     edi, edx
843
        mov     edi, edx
844
  .loop:
844
  .loop:
845
        cmp     edi, ecx
845
        cmp     edi, ecx
846
        jae     .fail
846
        jae     .fail
847
        lodsb
847
        lodsb
848
        scasb
848
        scasb
849
        je      .loop
849
        je      .loop
850
        test    al, al
850
        test    al, al
851
        jz      .done?
851
        jz      .done?
852
  .next:
852
  .next:
853
        inc     edx
853
        inc     edx
854
        jmp     .restart
854
        jmp     .restart
855
 
855
 
856
  .not_done:
856
  .not_done:
857
        inc     edi
857
        inc     edi
858
  .done?:
858
  .done?:
859
        cmp     byte[edi-1], ':'
859
        cmp     byte[edi-1], ':'
860
        je      .almost_done
860
        je      .almost_done
861
        cmp     byte[edi-1], ' '
861
        cmp     byte[edi-1], ' '
862
        je      .not_done
862
        je      .not_done
863
        cmp     byte[edi-1], 9  ; tab
863
        cmp     byte[edi-1], 9  ; tab
864
        je      .not_done
864
        je      .not_done
865
 
865
 
866
        jmp     .next
866
        jmp     .next
867
 
867
 
868
  .almost_done:                 ; FIXME: buffer overflow?
868
  .almost_done:                 ; FIXME: buffer overflow?
869
        dec     edi
869
        dec     edi
870
        DEBUGF  1, "Found header field\n"
870
        DEBUGF  1, "Found header field\n"
871
  .spaceloop:
871
  .spaceloop:
872
        inc     edi
872
        inc     edi
873
        cmp     byte[edi], ' '
873
        cmp     byte[edi], ' '
874
        je      .spaceloop
874
        je      .spaceloop
875
        cmp     byte[edi], 9    ; tab
875
        cmp     byte[edi], 9    ; tab
876
        je      .spaceloop
876
        je      .spaceloop
877
 
877
 
878
        mov     eax, edi
878
        mov     eax, edi
879
        pop     edi esi edx ecx ebx
879
        pop     edi esi edx ecx ebx
880
        ret
880
        ret
881
 
881
 
882
  .fail:
882
  .fail:
883
        pop     edi esi edx ecx ebx
883
        pop     edi esi edx ecx ebx
884
        xor     eax, eax
884
        xor     eax, eax
885
        ret
885
        ret
886
 
886
 
887
endp
887
endp
888
 
888
 
889
 
889
 
890
 
890
 
891
 
891
 
892
 
892
 
893
;;================================================================================================;;
893
;;================================================================================================;;
894
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
894
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
895
;;================================================================================================;;
895
;;================================================================================================;;
896
;! Internal procedures section                                                                    ;;
896
;! Internal procedures section                                                                    ;;
897
;;================================================================================================;;
897
;;================================================================================================;;
898
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
898
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
899
;;================================================================================================;;
899
;;================================================================================================;;
900
 
900
 
901
 
901
 
902
 
902
 
903
 
903
 
904
;;================================================================================================;;
904
;;================================================================================================;;
905
proc open_connection hostname, port ;/////////////////////////////////////////////////////////////;;
905
proc open_connection hostname, port ;/////////////////////////////////////////////////////////////;;
906
;;------------------------------------------------------------------------------------------------;;
906
;;------------------------------------------------------------------------------------------------;;
907
;? Connects to a HTTP server                                                                      ;;
907
;? Connects to a HTTP server                                                                      ;;
908
;;------------------------------------------------------------------------------------------------;;
908
;;------------------------------------------------------------------------------------------------;;
909
;> hostname     = ptr to ASCIIZ hostname                                                          ;;
909
;> hostname     = ptr to ASCIIZ hostname                                                          ;;
910
;> port         = port (x86 byte order)                                                           ;;
910
;> port         = port (x86 byte order)                                                           ;;
911
;;------------------------------------------------------------------------------------------------;;
911
;;------------------------------------------------------------------------------------------------;;
912
;< eax = 0 (error) / socketnum                                                                    ;;
912
;< eax = 0 (error) / socketnum                                                                    ;;
913
;;================================================================================================;;
913
;;================================================================================================;;
914
 
914
 
915
locals
915
locals
916
        sockaddr        dd ?
916
        sockaddr        dd ?
917
        socketnum       dd ?
917
        socketnum       dd ?
918
endl
918
endl
919
 
919
 
920
; Resolve the hostname
920
; Resolve the hostname
921
        DEBUGF  1, "Resolving hostname\n"
921
        DEBUGF  1, "Resolving hostname\n"
922
        push    esp     ; reserve stack place
922
        push    esp     ; reserve stack place
923
        push    esp     ; fourth parameter
923
        push    esp     ; fourth parameter
924
        push    0       ; third parameter
924
        push    0       ; third parameter
925
        push    0       ; second parameter
925
        push    0       ; second parameter
926
        push    [hostname]
926
        push    [hostname]
927
        call    [getaddrinfo]
927
        call    [getaddrinfo]
928
        pop     esi
928
        pop     esi
929
        test    eax, eax
929
        test    eax, eax
930
        jnz     .error1
930
        jnz     .error1
931
 
931
 
932
; getaddrinfo returns addrinfo struct, make the pointer to sockaddr struct
932
; getaddrinfo returns addrinfo struct, make the pointer to sockaddr struct
933
        mov     esi, [esi + addrinfo.ai_addr]
933
        mov     esi, [esi + addrinfo.ai_addr]
934
        mov     [sockaddr], esi
934
        mov     [sockaddr], esi
935
        mov     eax, [esi + sockaddr_in.sin_addr]
935
        mov     eax, [esi + sockaddr_in.sin_addr]
936
        test    eax, eax
936
        test    eax, eax
937
        jz      .error2
937
        jz      .error2
938
 
938
 
939
        DEBUGF  1, "Server ip=%u.%u.%u.%u\n", \
939
        DEBUGF  1, "Server ip=%u.%u.%u.%u\n", \
940
        [esi + sockaddr_in.sin_addr]:1, [esi + sockaddr_in.sin_addr + 1]:1, \
940
        [esi + sockaddr_in.sin_addr]:1, [esi + sockaddr_in.sin_addr + 1]:1, \
941
        [esi + sockaddr_in.sin_addr + 2]:1, [esi + sockaddr_in.sin_addr + 3]:1
941
        [esi + sockaddr_in.sin_addr + 2]:1, [esi + sockaddr_in.sin_addr + 3]:1
942
 
942
 
943
        mov     [esi + sockaddr_in.sin_family], AF_INET4
943
        mov     [esi + sockaddr_in.sin_family], AF_INET4
944
        mov     eax, [port]
944
        mov     eax, [port]
945
        xchg    al, ah
945
        xchg    al, ah
946
        mov     [esi + sockaddr_in.sin_port], ax
946
        mov     [esi + sockaddr_in.sin_port], ax
947
 
947
 
948
; Connect to the server.
948
; Connect to the server.
949
        mcall   socket, AF_INET4, SOCK_STREAM, 0
949
        mcall   socket, AF_INET4, SOCK_STREAM, 0
950
        test    eax, eax
950
        test    eax, eax
951
        jz      .error2
951
        jz      .error2
952
        mov     [socketnum], eax
952
        mov     [socketnum], eax
953
        DEBUGF  1, "Socket: 0x%x\n", eax
953
        DEBUGF  1, "Socket: 0x%x\n", eax
954
 
954
 
955
        mcall   connect, [socketnum], [sockaddr], 18
955
        mcall   connect, [socketnum], [sockaddr], 18
956
        test    eax, eax
956
        test    eax, eax
957
        jnz     .error2
957
        jnz     .error2
958
        DEBUGF  1, "Socket is now connected.\n"
958
        DEBUGF  1, "Socket is now connected.\n"
959
 
959
 
960
; free allocated memory
960
; free allocated memory
961
        push    [sockaddr]
961
        push    [sockaddr]
962
        call    [freeaddrinfo]
962
        call    [freeaddrinfo]
963
 
963
 
964
        mov     eax, [socketnum]
964
        mov     eax, [socketnum]
965
        ret
965
        ret
966
 
966
 
967
  .error2:
967
  .error2:
968
 
968
 
969
; free allocated memory
969
; free allocated memory
970
        push    [sockaddr]
970
        push    [sockaddr]
971
        call    [freeaddrinfo]
971
        call    [freeaddrinfo]
972
 
972
 
973
  .error1:
973
  .error1:
974
        xor     eax, eax
974
        xor     eax, eax
975
        ret
975
        ret
976
 
976
 
977
endp
977
endp
978
 
978
 
979
 
979
 
980
;;================================================================================================;;
980
;;================================================================================================;;
981
proc parse_url URL ;//////////////////////////////////////////////////////////////////////////////;;
981
proc parse_url URL ;//////////////////////////////////////////////////////////////////////////////;;
982
;;------------------------------------------------------------------------------------------------;;
982
;;------------------------------------------------------------------------------------------------;;
983
;? Split a given URL into hostname and pageaddr                                                   ;;
983
;? Split a given URL into hostname and pageaddr                                                   ;;
984
;;------------------------------------------------------------------------------------------------;;
984
;;------------------------------------------------------------------------------------------------;;
985
;> URL = ptr to ASCIIZ URL                                                                        ;;
985
;> URL = ptr to ASCIIZ URL                                                                        ;;
986
;;------------------------------------------------------------------------------------------------;;
986
;;------------------------------------------------------------------------------------------------;;
987
;< eax = 0 (error) / ptr to ASCIIZ hostname                                                       ;;
987
;< eax = 0 (error) / ptr to ASCIIZ hostname                                                       ;;
988
;< ebx = ptr to ASCIIZ pageaddr                                                                   ;;
988
;< ebx = ptr to ASCIIZ pageaddr                                                                   ;;
989
;;================================================================================================;;
989
;;================================================================================================;;
990
 
990
 
991
locals
991
locals
992
        urlsize         dd ?
992
        urlsize         dd ?
993
        hostname        dd ?
993
        hostname        dd ?
994
        pageaddr        dd ?
994
        pageaddr        dd ?
995
endl
995
endl
996
 
996
 
997
        DEBUGF  1, "parsing URL: %s\n", [URL]
997
        DEBUGF  1, "parsing URL: %s\n", [URL]
998
 
998
 
999
; remove any leading protocol text
999
; remove any leading protocol text
1000
        mov     esi, [URL]
1000
        mov     esi, [URL]
1001
        mov     ecx, URLMAXLEN
1001
        mov     ecx, URLMAXLEN
1002
        mov     ax, '//'
1002
        mov     ax, '//'
1003
  .loop1:
1003
  .loop1:
1004
        cmp     byte[esi], 0            ; end of URL?
1004
        cmp     byte[esi], 0            ; end of URL?
1005
        je      .url_ok                 ; yep, so not found
1005
        je      .url_ok                 ; yep, so not found
1006
        cmp     [esi], ax
1006
        cmp     [esi], ax
1007
        je      .skip_proto
1007
        je      .skip_proto
1008
        inc     esi
1008
        inc     esi
1009
        dec     ecx
1009
        dec     ecx
1010
        jnz     .loop1
1010
        jnz     .loop1
1011
 
1011
 
1012
        DEBUGF  1, "Invalid URL\n"
1012
        DEBUGF  1, "Invalid URL\n"
1013
        xor     eax, eax
1013
        xor     eax, eax
1014
        ret
1014
        ret
1015
 
1015
 
1016
  .skip_proto:
1016
  .skip_proto:
1017
        inc     esi                     ; skip the two '/'
1017
        inc     esi                     ; skip the two '/'
1018
        inc     esi
1018
        inc     esi
1019
        mov     [URL], esi              ; update pointer so it skips protocol
1019
        mov     [URL], esi              ; update pointer so it skips protocol
1020
        jmp     .loop1                  ; we still need to find the length of the URL
1020
        jmp     .loop1                  ; we still need to find the length of the URL
1021
 
1021
 
1022
  .url_ok:
1022
  .url_ok:
1023
        sub     esi, [URL]              ; calculate total length of URL
1023
        sub     esi, [URL]              ; calculate total length of URL
1024
        mov     [urlsize], esi
1024
        mov     [urlsize], esi
1025
 
1025
 
1026
 
1026
 
1027
; now look for page delimiter - it's a '/' character
1027
; now look for page delimiter - it's a '/' character
1028
        mov     ecx, esi                ; URL length
1028
        mov     ecx, esi                ; URL length
1029
        mov     edi, [URL]
1029
        mov     edi, [URL]
1030
        mov     al, '/'
1030
        mov     al, '/'
1031
        repne   scasb
1031
        repne   scasb
1032
        jne     @f
1032
        jne     @f
1033
        dec     edi                     ; return one char, '/' must be part of the pageaddr
1033
        dec     edi                     ; return one char, '/' must be part of the pageaddr
1034
        inc     ecx                     ;
1034
        inc     ecx                     ;
1035
  @@:
1035
  @@:
1036
        push    ecx edi                 ; remember the pointer and length of pageaddr
1036
        push    ecx edi                 ; remember the pointer and length of pageaddr
1037
 
1037
 
1038
        mov     ecx, edi
1038
        mov     ecx, edi
1039
        sub     ecx, [URL]
1039
        sub     ecx, [URL]
1040
        inc     ecx                     ; we will add a 0 byte at the end
1040
        inc     ecx                     ; we will add a 0 byte at the end
1041
        invoke  mem.alloc, ecx
1041
        invoke  mem.alloc, ecx
1042
        or      eax, eax
1042
        or      eax, eax
1043
        jz      .no_mem
1043
        jz      .no_mem
1044
 
1044
 
1045
        mov     [hostname], eax         ; copy hostname to buffer
1045
        mov     [hostname], eax         ; copy hostname to buffer
1046
        mov     edi, eax
1046
        mov     edi, eax
1047
        mov     esi, [URL]
1047
        mov     esi, [URL]
1048
        dec     ecx
1048
        dec     ecx
1049
        rep     movsb
1049
        rep     movsb
1050
        xor     al, al
1050
        xor     al, al
1051
        stosb
1051
        stosb
1052
 
1052
 
1053
        mov     [pageaddr], str_slash   ; assume there is no pageaddr
1053
        mov     [pageaddr], str_slash   ; assume there is no pageaddr
1054
        pop     esi ecx
1054
        pop     esi ecx
1055
        test    ecx, ecx
1055
        test    ecx, ecx
1056
        jz      .no_page
1056
        jz      .no_page
1057
        inc     ecx                     ; we will add a 0 byte at the end
1057
        inc     ecx                     ; we will add a 0 byte at the end
1058
        invoke  mem.alloc, ecx
1058
        invoke  mem.alloc, ecx
1059
        or      eax, eax
1059
        or      eax, eax
1060
        jz      .no_mem
1060
        jz      .no_mem
1061
 
1061
 
1062
        mov     [pageaddr], eax         ; copy pageaddr to buffer
1062
        mov     [pageaddr], eax         ; copy pageaddr to buffer
1063
        mov     edi, eax
1063
        mov     edi, eax
1064
        dec     ecx
1064
        dec     ecx
1065
        rep     movsb
1065
        rep     movsb
1066
        xor     al, al
1066
        xor     al, al
1067
        stosb
1067
        stosb
1068
  .no_page:
1068
  .no_page:
1069
 
1069
 
1070
        mov     eax, [hostname]
1070
        mov     eax, [hostname]
1071
        mov     ebx, [pageaddr]
1071
        mov     ebx, [pageaddr]
1072
 
1072
 
1073
        DEBUGF  1, "hostname: %s\n", eax
1073
        DEBUGF  1, "hostname: %s\n", eax
1074
        DEBUGF  1, "pageaddr: %s\n", ebx
1074
        DEBUGF  1, "pageaddr: %s\n", ebx
1075
 
1075
 
1076
        ret
1076
        ret
1077
 
1077
 
1078
  .no_mem:
1078
  .no_mem:
1079
        xor     eax, eax
1079
        xor     eax, eax
1080
        ret
1080
        ret
1081
 
1081
 
1082
endp
1082
endp
1083
 
1083
 
1084
 
1084
 
1085
;;================================================================================================;;
1085
;;================================================================================================;;
1086
proc ascii_dec ;//////////////////////////////////////////////////////////////////////////////////;;
1086
proc ascii_dec ;//////////////////////////////////////////////////////////////////////////////////;;
1087
;;------------------------------------------------------------------------------------------------;;
1087
;;------------------------------------------------------------------------------------------------;;
1088
;? Convert eax to ASCII decimal number                                                            ;;
1088
;? Convert eax to ASCII decimal number                                                            ;;
1089
;;------------------------------------------------------------------------------------------------;;
1089
;;------------------------------------------------------------------------------------------------;;
1090
;> eax = number                                                                                   ;;
1090
;> eax = number                                                                                   ;;
1091
;> edi = ptr where to write ASCII decimal number                                                  ;;
1091
;> edi = ptr where to write ASCII decimal number                                                  ;;
1092
;;------------------------------------------------------------------------------------------------;;
1092
;;------------------------------------------------------------------------------------------------;;
1093
;< /                                                                                              ;;
1093
;< /                                                                                              ;;
1094
;;================================================================================================;;
1094
;;================================================================================================;;
1095
 
1095
 
1096
        push    -'0'
1096
        push    -'0'
1097
        mov     ecx, 10
1097
        mov     ecx, 10
1098
  .loop:
1098
  .loop:
1099
        xor     edx, edx
1099
        xor     edx, edx
1100
        div     ecx
1100
        div     ecx
1101
        add     dl, '0'
1101
        add     dl, '0'
1102
        push    edx
1102
        push    edx
1103
        test    eax, eax
1103
        test    eax, eax
1104
        jnz     .loop
1104
        jnz     .loop
1105
 
1105
 
1106
  .loop2:
1106
  .loop2:
1107
        pop     eax
1107
        pop     eax
1108
        add     al, '0'
1108
        add     al, '0'
1109
        jz      .done
1109
        jz      .done
1110
        stosb
1110
        stosb
1111
        jmp     .loop2
1111
        jmp     .loop2
1112
  .done:
1112
  .done:
1113
 
1113
 
1114
        ret
1114
        ret
1115
 
1115
 
1116
endp
1116
endp
1117
 
1117
 
1118
 
1118
 
1119
;;================================================================================================;;
1119
;;================================================================================================;;
1120
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1120
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1121
;;================================================================================================;;
1121
;;================================================================================================;;
1122
;! Imported functions section                                                                     ;;
1122
;! Imported functions section                                                                     ;;
1123
;;================================================================================================;;
1123
;;================================================================================================;;
1124
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1124
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
1125
;;================================================================================================;;
1125
;;================================================================================================;;
1126
 
1126
 
1127
 
1127
 
1128
align 16
1128
align 16
1129
@IMPORT:
1129
@IMPORT:
1130
 
1130
 
1131
library \
1131
library \
1132
        libini, 'libini.obj', \
1132
        libini, 'libini.obj', \
1133
        network, 'network.obj'
1133
        network, 'network.obj'
1134
 
1134
 
1135
import  libini, \
1135
import  libini, \
1136
        ini.get_str, 'ini_get_str', \
1136
        ini.get_str, 'ini_get_str', \
1137
        ini.get_int, 'ini_get_int'
1137
        ini.get_int, 'ini_get_int'
1138
 
1138
 
1139
import  network,\
1139
import  network,\
1140
        getaddrinfo, 'getaddrinfo',\
1140
        getaddrinfo, 'getaddrinfo',\
1141
        freeaddrinfo,  'freeaddrinfo',\
1141
        freeaddrinfo,  'freeaddrinfo',\
1142
        inet_ntoa, 'inet_ntoa'
1142
        inet_ntoa, 'inet_ntoa'
1143
 
1143
 
1144
;;===========================================================================;;
1144
;;===========================================================================;;
1145
;;///////////////////////////////////////////////////////////////////////////;;
1145
;;///////////////////////////////////////////////////////////////////////////;;
1146
;;===========================================================================;;
1146
;;===========================================================================;;
1147
;! Exported functions section                                                ;;
1147
;! Exported functions section                                                ;;
1148
;;===========================================================================;;
1148
;;===========================================================================;;
1149
;;///////////////////////////////////////////////////////////////////////////;;
1149
;;///////////////////////////////////////////////////////////////////////////;;
1150
;;===========================================================================;;
1150
;;===========================================================================;;
1151
 
1151
 
1152
 
1152
 
1153
align 4
1153
align 4
1154
@EXPORT:
1154
@EXPORT:
1155
export  \
1155
export  \
1156
        lib_init                , 'lib_init'            , \
1156
        lib_init                , 'lib_init'            , \
1157
        0x00010001              , 'version'             , \
1157
        0x00010001              , 'version'             , \
1158
        HTTP_get                , 'get'                 , \
1158
        HTTP_get                , 'get'                 , \
1159
        HTTP_head               , 'head'                , \
1159
        HTTP_head               , 'head'                , \
1160
        HTTP_post               , 'post'                , \
1160
        HTTP_post               , 'post'                , \
1161
        find_header_field       , 'find_header_field'   , \
1161
        find_header_field       , 'find_header_field'   , \
1162
        HTTP_process            , 'process'             , \
1162
        HTTP_process            , 'process'             , \
1163
        HTTP_free               , 'free'                , \
1163
        HTTP_free               , 'free'                , \
1164
        HTTP_stop               , 'stop'
1164
        HTTP_stop               , 'stop'
1165
 
1165
 
1166
;        HTTP_put                , 'put'                 , \
1166
;        HTTP_put                , 'put'                 , \
1167
;        HTTP_delete             , 'delete'              , \
1167
;        HTTP_delete             , 'delete'              , \
1168
;        HTTP_trace              , 'trace'               , \
1168
;        HTTP_trace              , 'trace'               , \
1169
;        HTTP_connect            , 'connect'             , \
1169
;        HTTP_connect            , 'connect'             , \
1170
 
1170
 
1171
 
1171
 
1172
 
1172
 
1173
section '.data' data readable writable align 16
1173
section '.data' data readable writable align 16
1174
 
1174
 
1175
inifile         db '/sys/settings/network.ini', 0
1175
inifile         db '/sys/settings/network.ini', 0
1176
 
1176
 
1177
sec_proxy:
1177
sec_proxy:
1178
key_proxy       db 'proxy', 0
1178
key_proxy       db 'proxy', 0
1179
key_proxyport   db 'port', 0
1179
key_proxyport   db 'port', 0
1180
key_user        db 'user', 0
1180
key_user        db 'user', 0
1181
key_password    db 'password', 0
1181
key_password    db 'password', 0
1182
 
1182
 
1183
str_http11      db ' HTTP/1.1', 13, 10, 'Host: '
1183
str_http11      db ' HTTP/1.1', 13, 10, 'Host: '
1184
  .length       = $ - str_http11
1184
  .length       = $ - str_http11
1185
str_post_cl     db 13, 10, 'Content-Length: '
1185
str_post_cl     db 13, 10, 'Content-Length: '
1186
  .length       = $ - str_post_cl
1186
  .length       = $ - str_post_cl
1187
str_post_ct     db 13, 10, 'Content-Type: '
1187
str_post_ct     db 13, 10, 'Content-Type: '
1188
  .length       = $ - str_post_ct
1188
  .length       = $ - str_post_ct
1189
str_close       db 13, 10, 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
1189
str_close       db 13, 10, 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
1190
  .length       = $ - str_close
1190
  .length       = $ - str_close
1191
str_proxy_auth  db 13, 10, 'Proxy-Authorization: Basic '
1191
str_proxy_auth  db 13, 10, 'Proxy-Authorization: Basic '
1192
  .length       = $ - str_proxy_auth
1192
  .length       = $ - str_proxy_auth
1193
 
1193
 
1194
base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
1194
base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
1195
                db '0123456789+/'
1195
                db '0123456789+/'
1196
 
1196
 
1197
str_cl          db 'content-length', 0
1197
str_cl          db 'content-length', 0
1198
str_slash       db '/', 0
1198
str_slash       db '/', 0
1199
str_te          db 'transfer-encoding', 0
1199
str_te          db 'transfer-encoding', 0
1200
str_get         db 'GET ', 0
1200
str_get         db 'GET ', 0
1201
str_head        db 'HEAD ', 0
1201
str_head        db 'HEAD ', 0
1202
str_post        db 'POST ', 0
1202
str_post        db 'POST ', 0
1203
 
1203
 
1204
include_debug_strings
1204
include_debug_strings
1205
 
1205
 
1206
; uninitialized data
1206
; uninitialized data
1207
mem.alloc       dd ?
1207
mem.alloc       dd ?
1208
mem.free        dd ?
1208
mem.free        dd ?
1209
mem.realloc     dd ?
1209
mem.realloc     dd ?
1210
dll.load        dd ?
1210
dll.load        dd ?
1211
 
1211
 
1212
proxyAddr       rb 256
1212
proxyAddr       rb 256
1213
proxyUser       rb 256
1213
proxyUser       rb 256
1214
proxyPassword   rb 256
1214
proxyPassword   rb 256
1215
proxyPort       dd ?
1215
proxyPort       dd ?