Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3561 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2009-2013. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  downloader.asm - HTTP client for KolibriOS                     ;;
7
;;                                                                 ;;
8
;;  Based on HTTPC.asm for menuetos by ville turjanmaa             ;;
9
;;                                                                 ;;
10
;;  Programmers: Barsuk, Clevermouse, Marat Zakiyanov,             ;;
11
;;      Kirill Lipatov, dunkaist, HidnPlayr                        ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
3618 hidnplayr 18
URLMAXLEN       = 1024
19
BUFFERSIZE      = 4096
3561 hidnplayr 20
 
21
__DEBUG__       = 1
3618 hidnplayr 22
__DEBUG_LEVEL__ = 1
3561 hidnplayr 23
 
24
format binary as ""
25
 
26
use32
27
        org     0x0
28
 
29
        db      'MENUET01'      ; header
30
        dd      0x01            ; header version
31
        dd      START           ; entry point
32
        dd      IM_END          ; image size
3623 hidnplayr 33
        dd      I_END+0x1000    ; required memory
34
        dd      I_END+0x1000    ; esp
3561 hidnplayr 35
        dd      params          ; I_PARAM
36
        dd      0x0             ; I_Path
37
 
3618 hidnplayr 38
include '../../macros.inc'
39
include '../../proc32.inc'
40
include '../../network.inc'
3561 hidnplayr 41
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
3618 hidnplayr 42
include '../../dll.inc'
43
include '../../debug-fdo.inc'
3561 hidnplayr 44
 
45
START:
46
 
47
        mcall   68, 11                  ; init heap so we can allocate memory dynamically
48
 
49
; load libraries
50
        stdcall dll.Load, @IMPORT
51
        test    eax, eax
52
        jnz     exit
53
 
3566 hidnplayr 54
; prepare webAddr area
3561 hidnplayr 55
        mov     al, ' '
56
        mov     edi, webAddr
57
        mov     ecx, URLMAXLEN
58
        rep     stosb
59
        xor     eax, eax
60
        stosb
61
 
62
; prepare document area
63
        mov     al, '/'
64
        mov     edi, document
65
        stosb
66
        mov     al, ' '
67
        mov     ecx, URLMAXLEN-1
68
        rep     stosb
69
 
3623 hidnplayr 70
; load proxy settings
71
        invoke  ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr
72
        invoke  ini.get_int, inifile, sec_proxy, key_proxyport, 80
73
        mov     [proxyPort], eax
74
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
75
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
3561 hidnplayr 76
 
3623 hidnplayr 77
; check parameters
78
        cmp     byte[params], 0         ; no parameters ?
79
        je      reset_events            ; load the GUI
80
 
81
; we have an url, copy untill space or 0
3561 hidnplayr 82
        mov     esi, params
83
        mov     edi, document_user
3623 hidnplayr 84
        mov     ecx, 1024               ; max parameter size
85
        mov     [shared_name], 0
3561 hidnplayr 86
  .copy_param:
3623 hidnplayr 87
        lodsb
3561 hidnplayr 88
        test    al, al
89
        jz      .done
90
 
91
        cmp     al, ' '
3623 hidnplayr 92
        jz      .done_with_shared
3561 hidnplayr 93
 
3623 hidnplayr 94
        stosb
95
        dec     ecx
96
        jnz     .copy_param
97
        DEBUGF  2, "Invalid parameters\n"
98
        jmp     exit
3561 hidnplayr 99
 
3623 hidnplayr 100
  .done_with_shared:
101
        mov     [shared_name], esi
3561 hidnplayr 102
  .done:
3623 hidnplayr 103
        xor     al, al
104
        stosb
3561 hidnplayr 105
 
3623 hidnplayr 106
 
107
download:
108
 
109
        DEBUGF  1, "Starting download\n"
110
 
111
        call    parse_url
3970 hidnplayr 112
 
113
        cmp     [server_ip], 0
3971 hidnplayr 114
        je      dns_error
3970 hidnplayr 115
 
3623 hidnplayr 116
        call    open_socket
117
        call    send_request
118
 
119
        mcall   68, 12, BUFFERSIZE      ; create buffer, we'll resize it later if needed..
120
        mov     [buf_ptr], eax
121
        mov     [buf_size], 0
122
 
123
        call    read_incoming_data
124
 
125
        mcall   close, [socketnum]
126
 
127
        call    parse_result
128
        call    save
129
 
130
        mcall   68, 13, [final_buffer]  ; free buffer
131
 
3971 hidnplayr 132
dns_error:
3623 hidnplayr 133
        cmp     byte [params], 0
134
        jne     exit
135
 
136
reset_events:
137
 
138
        DEBUGF  1, "resetting events\n"
139
 
3561 hidnplayr 140
; Report events
3623 hidnplayr 141
; defaults + mouse
3948 mario79 142
        mcall   40,EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE+EVM_MOUSE_FILTER
3561 hidnplayr 143
 
3623 hidnplayr 144
redraw:
3561 hidnplayr 145
        call    draw_window
146
 
147
still:
3623 hidnplayr 148
        DEBUGF  1, "waiting for events\n"
3572 hidnplayr 149
 
3566 hidnplayr 150
        mcall   10      ; wait here for event
3561 hidnplayr 151
 
3623 hidnplayr 152
        cmp     eax, EV_REDRAW
153
        je      redraw
154
 
155
        cmp     eax, EV_KEY
3561 hidnplayr 156
        je      key
157
 
3623 hidnplayr 158
        cmp     eax, EV_BUTTON
3561 hidnplayr 159
        je      button
160
 
3623 hidnplayr 161
        cmp     eax, EV_MOUSE
3561 hidnplayr 162
        je      mouse
163
 
3566 hidnplayr 164
        jmp     still
3561 hidnplayr 165
 
166
key:
167
        mcall   2       ; read key
168
 
169
        stdcall [edit_box_key], dword edit1
170
 
3566 hidnplayr 171
        cmp     ax, 13 shl 8
172
        je      download
3561 hidnplayr 173
 
174
        jmp     still
175
 
176
button:
177
 
178
        mcall   17      ; get id
3623 hidnplayr 179
 
3561 hidnplayr 180
        cmp     ah, 26
3566 hidnplayr 181
        jne     @f
182
        call    save_to_file
183
        jmp     still
184
  @@:
3561 hidnplayr 185
        cmp     ah, 1   ; button id=1 ?
3566 hidnplayr 186
        je      exit
3561 hidnplayr 187
 
3566 hidnplayr 188
        jmp     download
3561 hidnplayr 189
 
3566 hidnplayr 190
mouse:
191
        stdcall [edit_box_mouse], edit1
192
        jmp     still
193
 
3561 hidnplayr 194
exit:
3704 hidnplayr 195
        DEBUGF  1, "Exiting\n"
196
        or      eax, -1 ; close this program
3561 hidnplayr 197
        mcall
3566 hidnplayr 198
 
199
 
3623 hidnplayr 200
save:
201
        cmp     [shared_name], 0
202
        je      .use_file
3566 hidnplayr 203
 
3623 hidnplayr 204
        call    save_in_shared
205
        jmp     .done
3566 hidnplayr 206
 
3623 hidnplayr 207
  .use_file:
3566 hidnplayr 208
 
3623 hidnplayr 209
        call    save_to_file
3566 hidnplayr 210
 
3623 hidnplayr 211
  .done:
3566 hidnplayr 212
 
213
; if called from command line, then exit
214
        cmp     byte[params], 0
215
        jne     exit
3561 hidnplayr 216
 
3704 hidnplayr 217
        mov     ecx, [sc.work_text]
218
        or      ecx, 0x80000000
219
        mcall   4, <10, 93>, , download_complete
220
 
3566 hidnplayr 221
        ret
3561 hidnplayr 222
 
3566 hidnplayr 223
save_in_shared:
3561 hidnplayr 224
 
3623 hidnplayr 225
; open the shared memory area
226
        mov     esi, 1
227
        mcall   68, 22, [shared_name], , 1 ; SHM_OPEN+SHM_WRITE
3566 hidnplayr 228
        test    eax, eax
229
        jz      exit
3561 hidnplayr 230
 
3566 hidnplayr 231
        mov     ecx, [final_size]
3623 hidnplayr 232
; store the size
233
        mov     [eax], ecx
3561 hidnplayr 234
 
3623 hidnplayr 235
; now copy the data
3566 hidnplayr 236
        lea     edi, [eax+4]
237
        mov     esi, [final_buffer]
3623 hidnplayr 238
        mov     eax, ecx
3566 hidnplayr 239
        shr     ecx, 2
240
        rep     movsd
3623 hidnplayr 241
        mov     ecx, eax
3566 hidnplayr 242
        and     ecx, 3
243
        rep     movsb
244
 
3623 hidnplayr 245
        ret
3566 hidnplayr 246
 
247
 
3561 hidnplayr 248
;****************************************************************************
249
;    Function
3566 hidnplayr 250
;       save_to_file
251
;
252
;   Description
253
;
254
;
255
;****************************************************************************
256
 
257
save_to_file:
258
 
259
        DEBUGF  2, "Saving to file\n"
260
        mcall   70, fileinfo
261
 
262
        ret
263
 
264
 
265
;****************************************************************************
266
;    Function
3561 hidnplayr 267
;       send_request
268
;
269
;   Description
270
;       Transmits the GET request to the server.
271
;       This is done as GET then URL then HTTP/1.1', 13, 10, 13, 10 in 3 packets
272
;
273
;****************************************************************************
274
send_request:
275
 
276
        DEBUGF  1, "Sending request\n"
277
 
278
        mov     esi, string0
279
        mov     edi, request
280
        movsd
281
; If proxy is used, make absolute URI - prepend http://
282
        cmp     byte[proxyAddr], 0
283
        jz      .noproxy
284
        mov     dword[edi], 'http'
285
        mov     byte[edi+4], ':'
286
        mov     word[edi+5], '//'
287
        add     edi, 7
288
        mov     esi, webAddr
289
 
290
  .copy_host_loop:
291
        lodsb
292
        cmp     al, ' '
293
        jz      .noproxy
294
        stosb
295
        jmp     .copy_host_loop
296
 
297
  .noproxy:
298
        xor     edx, edx ; 0
299
 
300
  .next_edx:
301
; Determine the length of the url to send in the GET request
302
        mov     al, [edx+document]
303
        cmp     al, ' '
304
        jbe     .document_done
305
        mov     [edi], al
306
        inc     edi
307
        inc     edx
308
        jmp     .next_edx
309
 
310
  .document_done:
311
        mov     esi, stringh
312
        mov     ecx, stringh_end-stringh
313
        rep     movsb
314
        xor     edx, edx ; 0
315
 
316
  .webaddr_next:
317
        mov     al, [webAddr + edx]
318
        cmp     al, ' '
319
        jbe     .webaddr_done
320
        mov     [edi], al
321
        inc     edi
322
        inc     edx
323
        jmp     .webaddr_next
324
 
325
  .webaddr_done:
326
        cmp     byte[proxyUser], 0
327
        jz      @f
328
        call    append_proxy_auth_header
329
    @@:
330
        mov     esi, connclose
331
        mov     ecx, connclose_end-connclose
332
        rep     movsb
333
 
334
        pusha
335
        mov     eax, 63
336
        mov     ebx, 1
337
        mov     edx, request
338
    @@:
339
        mov     cl, [edx]
340
        cmp     edx, edi
341
        jz      @f
342
        mcall
343
        inc     edx
344
        jmp     @b
345
    @@:
346
        popa
347
 
348
        mov     esi, edi
349
        sub     esi, request    ; length
350
        xor     edi, edi        ; flags
351
        mcall   send, [socketnum], request  ;' HTTP/1.1 .. '
3623 hidnplayr 352
 
3561 hidnplayr 353
        ret
354
 
355
;****************************************************************************
356
;    Function
357
;       read_incoming_data
358
;
359
;   Description
360
;       receive the web page from the server, storing it without processing
361
;
362
;****************************************************************************
363
read_incoming_data:
364
 
3564 hidnplayr 365
        DEBUGF  1, "Reading incoming data\n"
3561 hidnplayr 366
 
3566 hidnplayr 367
        mov     eax, [buf_ptr]
368
        mov     [pos], eax
3561 hidnplayr 369
  .read:
3737 hidnplayr 370
        mcall   recv, [socketnum], [pos], BUFFERSIZE, 0
3561 hidnplayr 371
        inc     eax             ; -1 = error (socket closed?)
4345 hidnplayr 372
        jz      .error
373
        dec     eax             ; 0 bytes means the remote end closed the connection
3561 hidnplayr 374
        jz      .no_more_data
3564 hidnplayr 375
 
376
        DEBUGF  1, "Got chunk of %u bytes\n", eax
3566 hidnplayr 377
 
378
        add     [buf_size], eax
3561 hidnplayr 379
        add     [pos], eax
380
        push    eax
3566 hidnplayr 381
        mov     ecx, [buf_size]
382
        add     ecx, BUFFERSIZE
383
        mcall   68, 20, , [buf_ptr]     ; reallocate memory block (make bigger)
384
        ; TODO: parse header and resize buffer only once
385
        pop     eax
386
        jmp     .read
4345 hidnplayr 387
 
388
  .error:
389
        DEBUGF  1, "Socket error: %u\n", ebx
3561 hidnplayr 390
 
391
  .no_more_data:
3566 hidnplayr 392
        mov     eax, [buf_ptr]
393
        sub     [pos], eax
3561 hidnplayr 394
 
3564 hidnplayr 395
        DEBUGF  1, "No more data\n"
396
 
3561 hidnplayr 397
        ret
398
 
399
 
400
 
401
; this function cuts header, and removes chunk sizes if doc is chunked
402
; in: buf_ptr, pos; out: buf_ptr, pos.
403
 
404
parse_result:
3566 hidnplayr 405
 
3561 hidnplayr 406
        mov     edi, [buf_ptr]
407
        mov     edx, [pos]
3566 hidnplayr 408
;        mov     [buf_size], edx
3561 hidnplayr 409
;       mcall   70, fileinfo_tmp
3564 hidnplayr 410
        DEBUGF  1, "Parsing result (%u bytes)\n", edx
3561 hidnplayr 411
 
412
; first, find end of headers
413
  .next_byte:
414
        cmp     dword[edi], 0x0a0d0a0d
415
        je      .end_of_headers
416
        inc     edi
417
        dec     edx
3736 hidnplayr 418
        ja      .next_byte
3564 hidnplayr 419
        DEBUGF  1, "Uh-oh, there's no end of header!\n"
3561 hidnplayr 420
; no end of headers. it's an error. let client see all those headers.
421
        ret
422
 
423
  .end_of_headers:
424
; here we look at headers and search content-length or transfer-encoding headers
3564 hidnplayr 425
        DEBUGF  1, "Found end of header\n"
3561 hidnplayr 426
 
427
        sub     edi, [buf_ptr]
428
        add     edi, 4
429
        mov     [body_pos], edi  ; store position where document body starts
430
        mov     [is_chunked], 0
431
; find content-length in headers
432
; not good method, but should work for 'Content-Length:'
433
        mov     esi, [buf_ptr]
434
        mov     edi, s_contentlength
435
        mov     ebx, [body_pos]
436
        xor     edx, edx ; 0
437
  .cl_next:
438
        mov     al, [esi]
439
        cmp     al, [edi + edx]
440
        jne     .cl_fail
441
        inc     edx
442
        cmp     edx, len_contentlength
443
        je      .cl_found
444
        jmp     .cl_incr
445
  .cl_fail:
446
        xor     edx, edx ; 0
447
  .cl_incr:
448
        inc     esi
449
        dec     ebx
450
        je      .cl_error
451
        jmp     .cl_next
452
  .cl_error:
3564 hidnplayr 453
        DEBUGF  1, "content-length not found\n"
3561 hidnplayr 454
 
455
; find 'chunked'
456
; äà, ÿ êîïèðóþ êîä, ýòî óæàñíî, íî ìíå õî÷åòñÿ, ÷òîáû ïîñêîðåå çàðàáîòàëî
457
; à òàì óæ îòðåôàêòîðþ
458
        mov     esi, [buf_ptr]
459
        mov     edi, s_chunked
460
        mov     ebx, [body_pos]
461
        xor     edx, edx ; 0
462
 
463
  .ch_next:
464
        mov     al, [esi]
465
        cmp     al, [edi + edx]
466
        jne     .ch_fail
467
        inc     edx
468
        cmp     edx, len_chunked
469
        je      .ch_found
470
        jmp     .ch_incr
471
 
472
  .ch_fail:
473
        xor     edx, edx ; 0
474
 
475
  .ch_incr:
476
        inc     esi
477
        dec     ebx
478
        je      .ch_error
479
        jmp     .ch_next
480
 
481
  .ch_error:
482
; if neither of the 2 headers is found, it's an error
483
;       DEBUGF  1, "transfer-encoding: chunked not found\n"
484
        mov     eax, [pos]
485
        sub     eax, [body_pos]
486
        jmp     .write_final_size
487
 
488
  .ch_found:
489
        mov     [is_chunked], 1
490
        mov     eax, [body_pos]
491
        add     eax, [buf_ptr]
492
        sub     eax, 2
493
        mov     [prev_chunk_end], eax
494
        jmp     parse_chunks
495
 
496
  .cl_found:
497
        call    read_number     ; eax = number from *esi
3564 hidnplayr 498
        DEBUGF  1, "Content length: %u\n", eax
3561 hidnplayr 499
 
500
  .write_final_size:
501
 
3564 hidnplayr 502
        mov     ebx, [buf_size]
3561 hidnplayr 503
        sub     ebx, [body_pos]
3564 hidnplayr 504
        cmp     eax, ebx
505
        jbe     .size_ok
3566 hidnplayr 506
        sub     eax, ebx
507
        DEBUGF  2, "%u bytes of data are missing!\n", eax
3564 hidnplayr 508
        mov     eax, ebx
509
  .size_ok:
510
        mov     [final_size], eax
3561 hidnplayr 511
 
3564 hidnplayr 512
        mov     ebx, [body_pos]
513
        add     ebx, [buf_ptr]
3561 hidnplayr 514
        mov     [final_buffer], ebx
3564 hidnplayr 515
 
3561 hidnplayr 516
        ret
517
 
518
parse_chunks:
3564 hidnplayr 519
        DEBUGF  1, "parse chunks\n"
3561 hidnplayr 520
        ; we have to look through the data and remove sizes of chunks we see
521
        ; 1. read size of next chunk
522
        ; 2. if 0, it's end. if not, continue.
523
        ; 3. make a good buffer and copy a chunk there
524
        xor     eax, eax
525
        mov     [final_buffer], eax      ; 0
526
        mov     [final_size], eax        ; 0
527
 
528
.read_size:
529
        mov     eax, [prev_chunk_end]
530
        mov     ebx, eax
531
        sub     ebx, [buf_ptr]
532
        mov     edx, eax
3564 hidnplayr 533
        DEBUGF  1, "rs "
3561 hidnplayr 534
        cmp     ebx, [pos]
535
        jae     chunks_end      ; not good
536
 
537
        call    read_hex        ; in: eax=pointer to text. out:eax=hex number, ebx=end of text.
538
        cmp     eax, 0
539
        jz      chunks_end
540
 
541
        add     ebx, 1
542
        mov     edx, ebx ; edx = size of size of chunk
543
 
544
        add     ebx, eax
545
        mov     [prev_chunk_end], ebx
546
 
3564 hidnplayr 547
        DEBUGF  1, "sz "
3561 hidnplayr 548
 
549
; do copying: from buf_ptr+edx to final_buffer+prev_final_size count eax
550
; realloc final buffer
551
        push    eax
552
        push    edx
553
        push    dword [final_size]
554
        add     [final_size], eax
555
        mcall   68, 20, [final_size], [final_buffer]
556
        mov     [final_buffer], eax
3564 hidnplayr 557
        DEBUGF  1, "re "
3561 hidnplayr 558
        pop     edi
559
        pop     esi
560
        pop     ecx
561
;       add     [pos], ecx
562
        add     edi, [final_buffer]
3564 hidnplayr 563
        DEBUGF  1, "cp "
3561 hidnplayr 564
 
565
        rep     movsb
566
        jmp     .read_size
567
 
568
chunks_end:
569
        DEBUGF  1, "chunks end\n"
3566 hidnplayr 570
        mcall   68, 13, [buf_ptr]       ; free old buffer
3561 hidnplayr 571
 
572
        ret
573
 
574
; reads content-length from [edi+ecx], result in eax
575
read_number:
576
        push    ebx
577
        xor     eax, eax
578
        xor     ebx, ebx
579
 
580
  .next:
581
        mov     bl, [esi]
582
 
583
        cmp     bl, '0'
584
        jb      .not_number
585
        cmp     bl, '9'
586
        ja      .not_number
587
        sub     bl, '0'
588
        shl     eax, 1
589
        lea     eax, [eax + eax * 4]     ; eax *= 10
590
        add     eax, ebx
591
 
592
  .not_number:
593
        cmp     bl, 13
594
        je      .done
595
        inc     esi
596
        jmp     .next
597
 
598
  .done:
599
        pop     ebx
600
        ret
601
 
602
; reads hex from eax, result in eax, end of text in ebx
603
read_hex:
604
        add     eax, 2
605
        mov     ebx, eax
606
        mov     eax, [ebx]
607
        mov     [deba], eax
608
 
609
        xor     eax, eax
610
        xor     ecx, ecx
3623 hidnplayr 611
  .next:
3561 hidnplayr 612
        mov     cl, [ebx]
613
        inc     ebx
614
 
615
        cmp     cl, 0x0d
616
        jz      .done
617
 
618
        or      cl, 0x20
619
        sub     cl, '0'
620
        jb      .bad
621
 
622
        cmp     cl, 0x9
623
        jbe     .adding
624
 
625
        sub     cl, 'a'-'0'-10
626
        cmp     cl, 0x0a
627
        jb      .bad
628
 
629
        cmp     cl, 0x0f
630
        ja      .bad
631
 
3623 hidnplayr 632
  .adding:
3561 hidnplayr 633
        shl     eax, 4
634
        or      eax, ecx
3623 hidnplayr 635
  .bad:
3561 hidnplayr 636
        jmp     .next
3623 hidnplayr 637
  .done:
3561 hidnplayr 638
 
639
        ret
640
 
641
;****************************************************************************
642
;    Function
3566 hidnplayr 643
;       open_socket
3561 hidnplayr 644
;
645
;   Description
3566 hidnplayr 646
;       opens the socket
3561 hidnplayr 647
;
648
;****************************************************************************
3566 hidnplayr 649
open_socket:
3561 hidnplayr 650
 
651
        DEBUGF  1, "opening socket\n"
652
 
653
        mov     edx, 80
654
        cmp     byte [proxyAddr], 0
655
        jz      @f
656
        mov     eax, [proxyPort]
657
        xchg    al, ah
658
        mov     [server_port], ax
659
    @@:
660
 
661
        mcall   socket, AF_INET4, SOCK_STREAM, 0
662
        mov     [socketnum], eax
663
        mcall   connect, [socketnum], sockaddr1, 18
3566 hidnplayr 664
 
3561 hidnplayr 665
        ret
666
 
667
 
668
;****************************************************************************
669
;    Function
670
;       parse_url
671
;
672
;   Description
673
;       parses the full url typed in by the user into a web address ( that
674
;       can be turned into an IP address by DNS ) and the page to display
675
;       DNS will be used to translate the web address into an IP address, if
676
;       needed.
677
;       url is at document_user and will be space terminated.
678
;       web address goes to webAddr and is space terminated.
679
;       ip address goes to server_ip
680
;       page goes to document and is space terminated.
681
;
682
;       Supported formats:
683
;       address
684
;        is optional, removed and ignored - only http supported
685
;       
is required. It can be an ip address or web address
686
;        is optional and must start with a leading / character
687
;
688
;****************************************************************************
689
parse_url:
690
; First, reset destination variables
691
        mov     al, ' '
692
        mov     edi, document
693
        mov     ecx, URLMAXLEN
694
        rep     stosb
695
        mov     edi, webAddr
696
        mov     ecx, URLMAXLEN
697
        rep     stosb
698
 
699
        mov     al, '/'
700
        mov     [document], al
701
 
702
        mov     esi, document_user
703
; remove any leading protocol text
704
        mov     ecx, URLMAXLEN
705
        mov     ax, '//'
706
 
707
pu_000:
708
        cmp     [esi], byte ' '         ; end of text?
709
        je      pu_002                  ; yep, so not found
710
        cmp     [esi], ax
711
        je      pu_001                  ; Found it, so esi+2 is start
712
        inc     esi
713
        loop    pu_000
714
 
715
pu_002:
716
; not found, so reset esi to start
717
        mov     esi, document_user-2
718
 
719
pu_001:
720
        add     esi, 2
721
        mov     ebx, esi ; save address of start of web address
722
        mov     edi, document_user + URLMAXLEN   ; end of string
723
; look for page delimiter - it's a '/' character
724
pu_003:
725
        cmp     [esi], byte ' '  ; end of text?
726
        je      pu_004          ; yep, so none found
727
        cmp     esi, edi         ; end of string?
728
        je      pu_004          ; yep, so none found
729
        cmp     [esi], byte '/'  ; delimiter?
730
        je      pu_005          ; yep - process it
731
        inc     esi
732
        jmp     pu_003
733
 
734
pu_005:
735
; copy page to document address
736
; esi = delimiter
737
        push    esi
738
        mov     ecx, edi         ; end of document_user
739
        mov     edi, document
740
 
741
pu_006:
742
        movsb
743
        cmp     esi, ecx
744
        je      pu_007          ; end of string?
745
        cmp     [esi], byte ' '  ; end of text
746
;       je      pu_007          ; äçåí-àññåìáëåð
747
;       jmp     pu_006          ; íå íàäî ïëîäèòü ñóùíîñòè ïî íàïðàñíó
748
        jne     pu_006
749
 
750
pu_007:
751
        pop     esi     ; point esi to '/' delimiter
752
 
753
pu_004:
754
; copy web address to webAddr
755
; start in ebx, end in esi-1
756
        mov     ecx, esi
757
        mov     esi, ebx
758
        mov     edi, webAddr
759
  @@:
760
        movsb
761
        cmp     esi, ecx
762
        jne     @r
763
        mov     byte [edi], 0
764
 
765
pu_009:
766
; For debugging, display resulting strings
3564 hidnplayr 767
        DEBUGF  2, "Downloadng %s\n", document_user
3561 hidnplayr 768
 
769
; Look up the ip address, or was it specified?
770
        mov     al, [proxyAddr]
771
        cmp     al, 0
772
        jnz     pu_015
773
        mov     al, [webAddr]
774
pu_015:
775
        cmp     al, '0'
776
        jb      pu_010  ; Resolve address
777
        cmp     al, '9'
778
        ja      pu_010  ; Resolve address
779
 
780
        DEBUGF  1, "GotIP\n"
781
 
782
; Convert address
783
; If proxy is given, get proxy address instead of server
784
        mov     esi, proxyAddr-1
785
        cmp     byte[esi+1], 0
786
        jne     pu_020
787
        mov     esi, webAddr-1
788
 
789
pu_020:
790
        mov     edi, server_ip
791
        xor     eax, eax
792
 
793
ip1:
794
        inc     esi
795
        cmp     [esi], byte '0'
796
        jb      ip2
797
        cmp     [esi], byte '9'
798
        ja      ip2
799
        imul    eax, 10
800
        movzx   ebx, byte [esi]
801
        sub     ebx, 48
802
        add     eax, ebx
803
        jmp     ip1
804
 
805
ip2:
806
        mov     [edi], al
807
        xor     eax, eax
808
        inc     edi
809
        cmp     edi, server_ip+3
810
        jbe     ip1
811
 
3623 hidnplayr 812
        ret
813
 
3561 hidnplayr 814
pu_010:
815
        DEBUGF  1, "Resolving %s\n", webAddr
816
 
817
; resolve name
818
        push    esp     ; reserve stack place
819
        push    esp     ; fourth parameter
820
        push    0       ; third parameter
821
        push    0       ; second parameter
822
        push    webAddr
823
        call    [getaddrinfo]
824
        pop     esi
3564 hidnplayr 825
; TODO: handle error
3561 hidnplayr 826
;        test    eax, eax
827
;        jnz     .fail_dns
828
 
3564 hidnplayr 829
; fill in ip
3561 hidnplayr 830
        mov     eax, [esi + addrinfo.ai_addr]
831
        mov     eax, [eax + sockaddr_in.sin_addr]
832
        mov     [server_ip], eax
833
 
3736 hidnplayr 834
; free allocated memory
835
        push    esi
836
        call    [freeaddrinfo]
837
 
3561 hidnplayr 838
        DEBUGF  1, "Resolved to %u.%u.%u.%u\n", [server_ip]:1, [server_ip + 1]:1, [server_ip + 2]:1, [server_ip + 3]:1
839
 
840
        ret
841
 
842
;***************************************************************************
843
;   Function
844
;       append_proxy_auth_header
845
;
846
;   Description
847
;       Append header to HTTP request for proxy authentification
848
;
849
;***************************************************************************
850
append_proxy_auth_header:
851
        mov     esi, proxy_auth_basic
852
        mov     ecx, proxy_auth_basic_end - proxy_auth_basic
853
        rep     movsb
854
; base64-encode string :
855
        mov     esi, proxyUser
856
 
857
apah000:
858
        lodsb
859
        test    al, al
860
        jz      apah001
861
        call    encode_base64_byte
862
        jmp     apah000
863
 
864
apah001:
865
        mov     al, ':'
866
        call    encode_base64_byte
867
        mov     esi, proxyPassword
868
 
869
apah002:
870
        lodsb
871
        test    al, al
872
        jz      apah003
873
        call    encode_base64_byte
874
        jmp     apah002
875
 
876
apah003:
877
        call    encode_base64_final
878
        ret
879
 
880
encode_base64_byte:
881
        inc     ecx
882
        shl     edx, 8
883
        mov     dl, al
884
        cmp     ecx, 3
885
        je      ebb001
886
        ret
887
 
888
ebb001:
889
        shl     edx, 8
890
        inc     ecx
891
 
892
ebb002:
893
        rol     edx, 6
894
        xor     eax, eax
895
        xchg    al, dl
896
        mov     al, [base64_table+eax]
897
        stosb
898
        loop    ebb002
899
        ret
900
 
901
encode_base64_final:
902
        mov     al, 0
903
        test    ecx, ecx
904
        jz      ebf000
905
        call    encode_base64_byte
906
        test    ecx, ecx
907
        jz      ebf001
908
        call    encode_base64_byte
909
        mov     byte [edi-2], '='
910
 
911
ebf001:
912
        mov     byte [edi-1], '='
913
 
914
ebf000:
915
        ret
916
 
917
;   *********************************************
918
;   *******  WINDOW DEFINITIONS AND DRAW ********
919
;   *********************************************
920
 
921
draw_window:
922
 
923
        mcall   12, 1
924
 
925
        mcall   48, 3, sc, 40 ;get system colors
926
 
927
        mov     edx, [sc.work]
928
        or      edx, 0x34000000
929
        mcall   0, <50, 370>, <350, 140>, , 0, title   ;draw window
930
 
931
        mov     ecx, [sc.work_text]
932
        or      ecx, 80000000h
933
        mcall   4, <14, 14>, , type_pls ;"URL:"
934
 
935
        edit_boxes_set_sys_color edit1, editboxes_end, sc
936
        stdcall [edit_box_draw], edit1
937
 
938
; RELOAD
939
        mcall   8, <90, 68>, <54, 16>, 22, [sc.work_button]
940
; STOP
941
        mcall   , <166, 50>, <54, 16>, 24
942
; SAVE
943
        mcall   , <224, 54>, , 26
944
; BUTTON TEXT
945
        mov     ecx, [sc.work_button_text]
946
        or      ecx, 80000000h
947
        mcall   4, <102, 59>, , button_text
948
 
949
        mcall   12, 2 ; end window redraw
3623 hidnplayr 950
 
3561 hidnplayr 951
        ret
3566 hidnplayr 952
 
953
 
3561 hidnplayr 954
;-----------------------------------------------------------------------------
955
; Data area
956
;-----------------------------------------------------------------------------
957
align   4
958
@IMPORT:
959
 
960
library libini, 'libini.obj', \
961
        box_lib, 'box_lib.obj', \
962
        network, 'network.obj'
963
 
964
import  libini, \
965
        ini.get_str, 'ini_get_str', \
966
        ini.get_int, 'ini_get_int'
967
 
968
import  box_lib, \
969
        edit_box_draw, 'edit_box', \
970
        edit_box_key, 'edit_box_key', \
971
        edit_box_mouse, 'edit_box_mouse'
972
 
973
import  network,\
974
        getaddrinfo,    'getaddrinfo',\
975
        freeaddrinfo,   'freeaddrinfo',\
976
        inet_ntoa,      'inet_ntoa'
977
 
978
;---------------------------------------------------------------------
979
fileinfo        dd 2, 0, 0
980
final_size      dd 0
981
final_buffer    dd 0
982
                db '/rd/1/.download', 0
983
 
984
body_pos        dd 0
985
buf_size        dd 0
986
buf_ptr         dd 0
987
 
988
deba            dd 0
989
                db 0
990
 
991
;---------------------------------------------------------------------
992
 
993
mouse_dd        dd 0
994
edit1           edit_box 295, 48, 10, 0xffffff, 0xff, 0x80ff, 0, 0x8000, URLMAXLEN, document_user, mouse_dd, ed_focus+ed_always_focus, 7, 7
995
editboxes_end:
996
 
997
;---------------------------------------------------------------------
998
 
999
include_debug_strings
1000
 
1001
;---------------------------------------------------------------------
1002
 
1003
type_pls        db 'URL:', 0
1004
button_text     db 'DOWNLOAD     STOP     RESAVE', 0
1005
download_complete db 'File saved as /rd/1/.download', 0
1006
title           db 'HTTP Downloader', 0
1007
 
1008
;---------------------------------------------------------------------
1009
s_contentlength db 'Content-Length:'
1010
len_contentlength = 15
1011
 
1012
s_chunked       db 'Transfer-Encoding: chunked'
1013
len_chunked     = $ - s_chunked
1014
 
1015
string0:        db 'GET '
1016
 
1017
stringh                 db ' HTTP/1.1', 13, 10, 'Host: '
1018
stringh_end:
1019
proxy_auth_basic        db 13, 10, 'Proxy-Authorization: Basic '
1020
proxy_auth_basic_end:
1021
connclose               db 13, 10, 'User-Agent: Kolibrios Downloader', 13, 10, 'Connection: Close', 13, 10, 13, 10
1022
connclose_end:
1023
 
1024
base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
1025
                db '0123456789+/'
1026
 
4101 mario79 1027
inifile         db '/sys/settings/network.ini', 0
3561 hidnplayr 1028
 
1029
sec_proxy:
1030
key_proxy       db 'proxy', 0
1031
key_proxyport   db 'port', 0
1032
key_user        db 'user', 0
1033
key_password    db 'password', 0
1034
 
1035
sockaddr1:
1036
                dw AF_INET4
1037
server_port     dw 0x5000       ; 80
1038
server_ip       dd 0
1039
                rb 10
1040
 
1041
proxyPort       dd 80
1042
 
1043
shared_name     dd 0
1044
 
1045
;---------------------------------------------------------------------
1046
document_user   db 'http://', 0
1047
;---------------------------------------------------------------------
1048
IM_END:
1049
;---------------------------------------------------------------------
1050
                rb URLMAXLEN-(IM_END - document_user)
1051
;---------------------------------------------------------------------
1052
                sc system_colors
1053
;---------------------------------------------------------------------
1054
align 4
1055
document        rb URLMAXLEN
1056
;---------------------------------------------------------------------
1057
align 4
1058
webAddr         rb URLMAXLEN+1
1059
;---------------------------------------------------------------------
3566 hidnplayr 1060
pos             dd ?
1061
socketnum       dd ?
1062
is_chunked      dd ?
1063
prev_chunk_end  dd ?
1064
cur_chunk_size  dd ?
1065
;---------------------------------------------------------------------
3561 hidnplayr 1066
 
1067
params          rb 1024
1068
 
1069
request         rb 256
1070
 
1071
proxyAddr       rb 256
1072
proxyUser       rb 256
1073
proxyPassword   rb 256
1074
 
1075
I_END:
1076