instaweb.ss
#lang scheme/base

(require scheme/contract
         net/url
         web-server/http
         web-server/private/connection-manager
         "defaults.ss"
         "dispatcher.ss"
         "run-server.ss")

; Main entry points ------------------------------

;  [#:port                integer]
;  [#:listen-ip           (U string #f)]
;  [#:servlet-path        (U path string #f)]
;  [#:servlet-namespace   (listof require-spec)]
;  [#:servlet-exn-handler (-> url? exn? response?)]
;  [#:htdocs-paths        (listof (U path string))]
;  [#:mime-types-path     path]
; ->
;  void
(define (instaweb #:port                [port                8765]
                  #:listen-ip           [listen-ip           "127.0.0.1"]
                  #:servlet-path        [servlet-path        default-servlet-path]
                  #:servlet-namespace   [servlet-namespace   default-servlet-namespace]
                  #:servlet-exn-handler [servlet-exn-handler default-servlet-exn-handler]
                  #:htdocs-paths        [htdocs-paths        default-htdocs-paths]
                  #:mime-types-path     [mime-types-path     default-mime-types-path])
  (instaweb/dispatcher (make-application-dispatcher
                        #:servlet-path        (build-path (current-directory) servlet-path)
                        #:servlet-exn-handler servlet-exn-handler
                        #:servlet-namespace   servlet-namespace)
                       #:port            port 
                       #:listen-ip       listen-ip
                       #:htdocs-paths    htdocs-paths
                       #:mime-types-path mime-types-path))

;  (connection request -> void)
;  [#:port              integer]
;  [#listen-ip          (U string #f)]
;  [#:htdocs-paths      (listof (U path string))]
;  [#:mime-types-path   path]
; ->
;  void
(define (instaweb/dispatcher dispatcher
                             #:port              [port            8765]
                             #:listen-ip         [listen-ip       "127.0.0.1"]
                             #:htdocs-paths      [htdocs-paths    default-htdocs-paths]
                             #:mime-types-path   [mime-types-path default-mime-types-path])
  (define instaweb-dispatcher
    (make-instaweb-dispatcher dispatcher #:htdocs-paths htdocs-paths #:mime-types-path mime-types-path))
  (define (run-server-thunk)
    (run-server port listen-ip instaweb-dispatcher))
  (parameterize
      ([print-hash-table #t]
       [print-struct #t]
       [error-print-width 1024]
       [error-print-context-length 50])
    (console-loop run-server-thunk)))

; Provide statements -----------------------------

(provide/contract
 [instaweb            (->* ()
                           (#:port natural-number/c
                                   #:listen-ip           (or/c string? false/c)
                                   #:servlet-path        (or/c path? string?)
                                   #:servlet-namespace   list?
                                   #:servlet-exn-handler (-> url? exn? response?)
                                   #:htdocs-paths        (listof (or/c path? string?))
                                   #:mime-types-path     (or/c path? string?))
                           void?)]
 [instaweb/dispatcher (->* ((-> connection? request? any))
                           (#:port natural-number/c
                                   #:listen-ip         (or/c string? false/c)
                                   #:htdocs-paths      (listof (or/c path? string?))
                                   #:mime-types-path   (or/c path? string?))
                           void?)])