322
322
323
323
(defun full-proxy-path (host port path)
324
324
(format nil " ~:[ http~; https~] ://~A ~:[ :~D ~; ~* ~] ~A "
325
- (= port 443 )
325
+ (eql port 443 )
326
326
host
327
- (or (= port 80 )
328
- (= port 443 ))
327
+ (or (eql port 80 )
328
+ (eql port 443 ))
329
329
port
330
330
path))
331
331
@@ -365,7 +365,7 @@ information."
365
365
(apply #' add-strings sink strings)
366
366
(add-newline sink)))
367
367
(add-line method " " path " HTTP/1.1" )
368
- (add-line " Host: " host (if (= port 80 ) " "
368
+ (add-line " Host: " host (if (eql port 80 ) " "
369
369
(format nil " :~D " port)))
370
370
(add-line " Connection: close" )
371
371
(add-line " User-Agent: " (user-agent-string))
@@ -589,24 +589,31 @@ the indexes in the header accordingly."
589
589
; ;; HTTP URL parsing
590
590
591
591
(defclass url ()
592
- ((hostname
592
+ ((scheme
593
+ :initarg :scheme
594
+ :accessor scheme
595
+ :initform nil )
596
+ (hostname
593
597
:initarg :hostname
594
598
:accessor hostname
595
599
:initform nil )
596
600
(port
597
601
:initarg :port
598
602
:accessor port
599
- :initform 80 )
603
+ :initform nil )
600
604
(path
601
605
:initarg :path
602
606
:accessor path
603
607
:initform " /" )))
604
608
605
609
(defun parse-urlstring (urlstring)
606
610
(setf urlstring (string-trim " " urlstring))
607
- (let* ((pos (mismatch urlstring " http://" :test ' char-equal))
611
+ (let* ((pos (position #\: urlstring))
612
+ (scheme (or (and pos (subseq urlstring 0 pos)) " http" ))
613
+ (pos (mismatch urlstring " ://" :test ' char-equal :start1 pos))
608
614
(mark pos)
609
615
(url (make-instance ' url)))
616
+ (setf (scheme url) scheme)
610
617
(labels ((save ()
611
618
(subseq urlstring mark pos))
612
619
(mark ()
@@ -673,13 +680,14 @@ the indexes in the header accordingly."
673
680
(defgeneric request-buffer (method url)
674
681
(:method (method url)
675
682
(setf url (url url))
676
- (make-request-buffer (hostname url) (port url) (path url)
683
+ (make-request-buffer (hostname url) (port url) (or ( path url) 80 )
677
684
:method method )))
678
685
679
686
(defun urlstring (url)
680
- (format nil " ~@[ http://~A ~]~@[ :~D ~] ~A "
687
+ (format nil " ~@[ ~A ://~]~@[ ~A ~]~@[ :~D ~] ~A "
688
+ (and (hostname url) (scheme url))
681
689
(hostname url)
682
- (and ( /= 80 ( port url)) (port url) )
690
+ (port url)
683
691
(path url)))
684
692
685
693
(defmethod print-object ((url url) stream )
@@ -690,6 +698,8 @@ the indexes in the header accordingly."
690
698
(setf url1 (url url1))
691
699
(setf url2 (url url2))
692
700
(make-instance ' url
701
+ :scheme (or (scheme url1)
702
+ (scheme url2))
693
703
:hostname (or (hostname url1)
694
704
(hostname url2))
695
705
:port (or (port url1)
@@ -780,10 +790,22 @@ the indexes in the header accordingly."
780
790
(too-many-redirects-count condition )
781
791
(too-many-redirects-url condition )))))
782
792
783
- (defun fetch (url file &key (follow-redirects t ) quietly
793
+ (defvar *fetch-scheme-functions*
794
+ ' ((" http" . http-fetch))
795
+ " assoc list to decide which scheme-function are called by FETCH function." )
796
+
797
+ (defun fetch (url file &rest rest )
798
+ " Request URL and write the body of the response to FILE."
799
+ (let* ((url (merge-urls url *default-url-defaults* ))
800
+ (call (cdr (assoc (scheme url) *fetch-scheme-functions* :test ' equal))))
801
+ (if call
802
+ (apply call (urlstring url) file rest )
803
+ (error " Unknow scheme ~S " url))))
804
+
805
+ (defun http-fetch (url file &key (follow-redirects t ) quietly
784
806
(if-exists :rename-and-delete )
785
807
(maximum-redirects *maximum-redirects* ))
786
- " Request URL and write the body of the response to FILE ."
808
+ " default scheme-function for http protocol ."
787
809
(setf url (merge-urls url *default-url-defaults* ))
788
810
(setf file (merge-pathnames file))
789
811
(let ((redirect-count 0 )
@@ -797,7 +819,7 @@ the indexes in the header accordingly."
797
819
(error ' too-many-redirects
798
820
:url original-url
799
821
:redirect-count redirect-count))
800
- (with-connection (connection (hostname connect-url) (port connect-url))
822
+ (with-connection (connection (hostname connect-url) (or ( port connect-url) 80 ))
801
823
(let ((cbuf (make-instance ' cbuf :connection connection))
802
824
(request (request-buffer " GET" url)))
803
825
(write-octets request connection)
0 commit comments