Subversion Repositories Kolibri OS

Rev

Rev 4345 | Rev 5540 | 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
4431 hidnplayr 825
        test    eax, eax
826
        jnz     .fail_dns
3561 hidnplayr 827
 
3564 hidnplayr 828
; fill in ip
3561 hidnplayr 829
        mov     eax, [esi + addrinfo.ai_addr]
830
        mov     eax, [eax + sockaddr_in.sin_addr]
831
        mov     [server_ip], eax
832
 
3736 hidnplayr 833
; free allocated memory
834
        push    esi
835
        call    [freeaddrinfo]
836
 
3561 hidnplayr 837
        DEBUGF  1, "Resolved to %u.%u.%u.%u\n", [server_ip]:1, [server_ip + 1]:1, [server_ip + 2]:1, [server_ip + 3]:1
838
 
839
        ret
840
 
4431 hidnplayr 841
  .fail_dns:
842
        DEBUGF  1, "DNS resolution failed\n"
843
        mov     [server_ip], 0
844
 
845
        ret
846
 
3561 hidnplayr 847
;***************************************************************************
848
;   Function
849
;       append_proxy_auth_header
850
;
851
;   Description
852
;       Append header to HTTP request for proxy authentification
853
;
854
;***************************************************************************
855
append_proxy_auth_header:
856
        mov     esi, proxy_auth_basic
857
        mov     ecx, proxy_auth_basic_end - proxy_auth_basic
858
        rep     movsb
859
; base64-encode string :
860
        mov     esi, proxyUser
861
 
862
apah000:
863
        lodsb
864
        test    al, al
865
        jz      apah001
866
        call    encode_base64_byte
867
        jmp     apah000
868
 
869
apah001:
870
        mov     al, ':'
871
        call    encode_base64_byte
872
        mov     esi, proxyPassword
873
 
874
apah002:
875
        lodsb
876
        test    al, al
877
        jz      apah003
878
        call    encode_base64_byte
879
        jmp     apah002
880
 
881
apah003:
882
        call    encode_base64_final
883
        ret
884
 
885
encode_base64_byte:
886
        inc     ecx
887
        shl     edx, 8
888
        mov     dl, al
889
        cmp     ecx, 3
890
        je      ebb001
891
        ret
892
 
893
ebb001:
894
        shl     edx, 8
895
        inc     ecx
896
 
897
ebb002:
898
        rol     edx, 6
899
        xor     eax, eax
900
        xchg    al, dl
901
        mov     al, [base64_table+eax]
902
        stosb
903
        loop    ebb002
904
        ret
905
 
906
encode_base64_final:
907
        mov     al, 0
908
        test    ecx, ecx
909
        jz      ebf000
910
        call    encode_base64_byte
911
        test    ecx, ecx
912
        jz      ebf001
913
        call    encode_base64_byte
914
        mov     byte [edi-2], '='
915
 
916
ebf001:
917
        mov     byte [edi-1], '='
918
 
919
ebf000:
920
        ret
921
 
922
;   *********************************************
923
;   *******  WINDOW DEFINITIONS AND DRAW ********
924
;   *********************************************
925
 
926
draw_window:
927
 
928
        mcall   12, 1
929
 
930
        mcall   48, 3, sc, 40 ;get system colors
931
 
932
        mov     edx, [sc.work]
933
        or      edx, 0x34000000
934
        mcall   0, <50, 370>, <350, 140>, , 0, title   ;draw window
935
 
936
        mov     ecx, [sc.work_text]
937
        or      ecx, 80000000h
938
        mcall   4, <14, 14>, , type_pls ;"URL:"
939
 
940
        edit_boxes_set_sys_color edit1, editboxes_end, sc
941
        stdcall [edit_box_draw], edit1
942
 
943
; RELOAD
944
        mcall   8, <90, 68>, <54, 16>, 22, [sc.work_button]
945
; STOP
946
        mcall   , <166, 50>, <54, 16>, 24
947
; SAVE
948
        mcall   , <224, 54>, , 26
949
; BUTTON TEXT
950
        mov     ecx, [sc.work_button_text]
951
        or      ecx, 80000000h
952
        mcall   4, <102, 59>, , button_text
953
 
954
        mcall   12, 2 ; end window redraw
3623 hidnplayr 955
 
3561 hidnplayr 956
        ret
3566 hidnplayr 957
 
958
 
3561 hidnplayr 959
;-----------------------------------------------------------------------------
960
; Data area
961
;-----------------------------------------------------------------------------
962
align   4
963
@IMPORT:
964
 
965
library libini, 'libini.obj', \
966
        box_lib, 'box_lib.obj', \
967
        network, 'network.obj'
968
 
969
import  libini, \
970
        ini.get_str, 'ini_get_str', \
971
        ini.get_int, 'ini_get_int'
972
 
973
import  box_lib, \
974
        edit_box_draw, 'edit_box', \
975
        edit_box_key, 'edit_box_key', \
976
        edit_box_mouse, 'edit_box_mouse'
977
 
978
import  network,\
979
        getaddrinfo,    'getaddrinfo',\
980
        freeaddrinfo,   'freeaddrinfo',\
981
        inet_ntoa,      'inet_ntoa'
982
 
983
;---------------------------------------------------------------------
984
fileinfo        dd 2, 0, 0
985
final_size      dd 0
986
final_buffer    dd 0
987
                db '/rd/1/.download', 0
988
 
989
body_pos        dd 0
990
buf_size        dd 0
991
buf_ptr         dd 0
992
 
993
deba            dd 0
994
                db 0
995
 
996
;---------------------------------------------------------------------
997
 
998
mouse_dd        dd 0
999
edit1           edit_box 295, 48, 10, 0xffffff, 0xff, 0x80ff, 0, 0x8000, URLMAXLEN, document_user, mouse_dd, ed_focus+ed_always_focus, 7, 7
1000
editboxes_end:
1001
 
1002
;---------------------------------------------------------------------
1003
 
1004
include_debug_strings
1005
 
1006
;---------------------------------------------------------------------
1007
 
1008
type_pls        db 'URL:', 0
1009
button_text     db 'DOWNLOAD     STOP     RESAVE', 0
1010
download_complete db 'File saved as /rd/1/.download', 0
1011
title           db 'HTTP Downloader', 0
1012
 
1013
;---------------------------------------------------------------------
1014
s_contentlength db 'Content-Length:'
1015
len_contentlength = 15
1016
 
1017
s_chunked       db 'Transfer-Encoding: chunked'
1018
len_chunked     = $ - s_chunked
1019
 
1020
string0:        db 'GET '
1021
 
1022
stringh                 db ' HTTP/1.1', 13, 10, 'Host: '
1023
stringh_end:
1024
proxy_auth_basic        db 13, 10, 'Proxy-Authorization: Basic '
1025
proxy_auth_basic_end:
1026
connclose               db 13, 10, 'User-Agent: Kolibrios Downloader', 13, 10, 'Connection: Close', 13, 10, 13, 10
1027
connclose_end:
1028
 
1029
base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
1030
                db '0123456789+/'
1031
 
4101 mario79 1032
inifile         db '/sys/settings/network.ini', 0
3561 hidnplayr 1033
 
1034
sec_proxy:
1035
key_proxy       db 'proxy', 0
1036
key_proxyport   db 'port', 0
1037
key_user        db 'user', 0
1038
key_password    db 'password', 0
1039
 
1040
sockaddr1:
1041
                dw AF_INET4
1042
server_port     dw 0x5000       ; 80
1043
server_ip       dd 0
1044
                rb 10
1045
 
1046
proxyPort       dd 80
1047
 
1048
shared_name     dd 0
1049
 
1050
;---------------------------------------------------------------------
1051
document_user   db 'http://', 0
1052
;---------------------------------------------------------------------
1053
IM_END:
1054
;---------------------------------------------------------------------
1055
                rb URLMAXLEN-(IM_END - document_user)
1056
;---------------------------------------------------------------------
1057
                sc system_colors
1058
;---------------------------------------------------------------------
1059
align 4
1060
document        rb URLMAXLEN
1061
;---------------------------------------------------------------------
1062
align 4
1063
webAddr         rb URLMAXLEN+1
1064
;---------------------------------------------------------------------
3566 hidnplayr 1065
pos             dd ?
1066
socketnum       dd ?
1067
is_chunked      dd ?
1068
prev_chunk_end  dd ?
1069
cur_chunk_size  dd ?
1070
;---------------------------------------------------------------------
3561 hidnplayr 1071
 
1072
params          rb 1024
1073
 
1074
request         rb 256
1075
 
1076
proxyAddr       rb 256
1077
proxyUser       rb 256
1078
proxyPassword   rb 256
1079
 
1080
I_END:
1081