Subversion Repositories Kolibri OS

Rev

Rev 4983 | Rev 5534 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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