Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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