Wapp

Forum
Login

HTTPS/SSL Support

(1) By omarpta on 2018-09-17 10:04:22 [link]

Hi there is some way to provide https protocol with certificate using wapp?

Thanks, Omar

(2) By drh on 2018-09-17 11:43:51 [link] in reply to 1

I run Wapp apps as CGI behind a traditional webserver that takes care of the TSL for me. There is (current) no way for wapp to do the TSL itself.

But your patches are welcomed!

(3) By omarpta on 2018-09-17 11:54:56 [link] in reply to 2

Ok thanks. What about headers? How can i get headers from the request and set some header?

(4) By drh on 2018-09-17 13:40:34 [link] in reply to 3

I don't understand the question. Please elaborate.

(5) By omarpta on 2018-09-17 14:30:52 in reply to 4

I'm creating some Basic Authentication engine using Wapp.

https://en.wikipedia.org/wiki/Basicaccessauthentication#Server_side

And end up with this implementation. I don't know if it's the best way to do it. (sorry about formatting)

proc wapp-page-flush {} {

set authorization [wapp-param .hdr:AUTHORIZATION]

if {$authorization eq ""} {

wapp-reply-code 401

wapp-reply-extra "WWW-Authenticate" "Basic realm=\"User Visible Realm\""

} else {

wapp-subst {

  received authorization, verifying user

}  

}

}

(6) By jmeh on 2019-07-26 08:34:43 [link] in reply to 1

Here's a little patch for wapp.tcl with tls integration:

# Start up a listening socket.  Arrange to invoke wappInt-new-connection
# for each inbound HTTP connection.
#
#    port            Listen on this TCP port.  0 means to select a port
#                    that is not currently in use
#
#    wappmode        One of "scgi", "remote-scgi", "server", or "local".
#
#    fromip          If not {}, then reject all requests from IP addresses
#                    other than $fromip
#
#    certfile        File name of a TLS certificate
#
#    keyfile         File name of a TLS private key
#
proc wappInt-start-listener {port wappmode fromip certfile keyfile} {
  if {string match *scgi $wappmode} {
    set type SCGI
    set server [list wappInt-new-connection \
                wappInt-scgi-readable $wappmode $fromip]list wappInt-new-connection \
                wappInt-scgi-readable $wappmode $fromip
  } else {
    set type HTTP
    set server [list wappInt-new-connection \
                wappInt-http-readable $wappmode $fromip]list wappInt-new-connection \
                wappInt-http-readable $wappmode $fromip
  }
  if {$wappmode=="local" || $wappmode=="scgi"} {
    set x socket -server $server -myaddr 127.0.0.1 $port
  } else {
    if {$certfile ne {} && $keyfile ne {}} {
      if {!file readable $certfile} {
        return -code error "cannot read CERT file \"$certfile\""
      }
      if {!file readable $keyfile} {
        return -code error "cannot read KEY file \"$keyfile\""
      }
      package require tls
      tls::init -require no -request no -certfile $certfile -keyfile $keyfile
      set x tls::socket -server $server $port
      set type HTTPS
    } else {
      set x socket -server $server $port
    }
  }
  set coninfo chan configure $x -sockname
  set port lindex $coninfo 2
  if {$wappmode=="local"} {
    wappInt-start-browser http://127.0.0.1:$port/
  } elseif {$fromip!=""} {
    puts "Listening for $type requests on TCP port $port from IP $fromip"
  } else {
    puts "Listening for $type requests on TCP port $port"
  }
}

# Start up the wapp framework. Parameters are a list passed as the # single argument. # # -server $PORT Listen for HTTP requests on this TCP port $PORT # # -local $PORT Listen for HTTP requests on 127.0.0.1:$PORT # # -scgi $PORT Listen for SCGI requests on 127.0.0.1:$PORT # # -remote-scgi $PORT Listen for SCGI requests on TCP port $PORT # # -cgi Handle a single CGI request # # To start a HTTPS server you must specify a certificate and a private key. # (See tls::init for a detailed description.) # # -certfile $FILENAME Name of certificate file # # -keyfile $FILENAME Name of private key file # # With no arguments, the behavior is called "auto". In "auto" mode, # if the GATEWAY_INTERFACE environment variable indicates CGI, then run # as CGI. Otherwise, start an HTTP server bound to the loopback address # only, on an arbitrary TCP port, and automatically launch a web browser # on that TCP port. # # Additional options: # # -fromip GLOB Reject any incoming request where the remote # IP address does not match the GLOB pattern. This # value defaults to '127.0.0.1' for -local and -scgi. # # -nowait Do not wait in the event loop. Return immediately # after all event handlers are established. # # -trace "puts" each request URL as it is handled, for # debugging # # -lint Run wapp-safety-check on the application instead # of running the application itself # # -Dvar=value Set TCL global variable "var" to "value" # # proc wapp-start {arglist} { global env set mode auto set port 0 set nowait 0 set fromip {} set certfile {} set keyfile {} set n llength $arglist for {set i 0} {$i<$n} {incr i} { set term lindex $arglist $i if {string match --* $term} {set term string range $term 1 end} switch -glob -- $term { -server { incr i; set mode "server" set port lindex $arglist $i } -local { incr i; set mode "local" set fromip 127.0.0.1 set port lindex $arglist $i } -scgi { incr i; set mode "scgi" set fromip 127.0.0.1 set port lindex $arglist $i } -remote-scgi { incr i; set mode "remote-scgi" set port lindex $arglist $i } -cgi { set mode "cgi" } -fromip { incr i set fromip lindex $arglist $i } -nowait { set nowait 1 } -trace { proc wappInt-trace {} { set q wapp-param QUERY_STRING set uri wapp-param BASE_URLwapp-param PATH_INFO if {$q!=""} {append uri ?$q} puts $uri } } -lint { set res wapp-safety-check if {$res!=""} { puts "Potential problems in this code:" puts $res exit 1 } else { exit } } -D*=* { if {regexp {^.D([^=+)=(.*)$} $term all var val]} { set ::$var $val } } -certfile { set certfile lindex $arglist [incr i] } -keyfile { set keyfile lindex $arglist [incr i] } default { error "unknown option: $term" } } } if {$mode=="auto"} { if {info exists env(GATEWAY_INTERFACE) && string match CGI/1.* $env(GATEWAY_INTERFACE)} { set mode cgi } else { set mode local } } if {$mode=="cgi"} { wappInt-handle-cgi-request } else { wappInt-start-listener $port $mode $fromip $certfile $keyfile if {!$nowait} { vwait ::forever } } }

(7) By jmeh on 2019-07-26 08:43:20 [link] in reply to 6

Here's a little patch for wapp.tcl with tls integration:

# Start up a listening socket.  Arrange to invoke wappInt-new-connection
# for each inbound HTTP connection.
#
#    port            Listen on this TCP port.  0 means to select a port
#                    that is not currently in use
#
#    wappmode        One of "scgi", "remote-scgi", "server", or "local".
#
#    fromip          If not {}, then reject all requests from IP addresses
#                    other than $fromip
#
#    certfile        File name of a TLS certificate
#
#    keyfile         File name of a TLS private key
#
proc wappInt-start-listener {port wappmode fromip certfile keyfile} {
  if {[string match *scgi $wappmode]} {
    set type SCGI
    set server [list wappInt-new-connection \
                wappInt-scgi-readable $wappmode $fromip]
  } else {
    set type HTTP
    set server [list wappInt-new-connection \
                wappInt-http-readable $wappmode $fromip]
  }
  if {$wappmode=="local" || $wappmode=="scgi"} {
    set x [socket -server $server -myaddr 127.0.0.1 $port]
  } else {
    if {$certfile ne {} && $keyfile ne {}} {
      if {![file readable $certfile]} {
        return -code error "cannot read CERT file \"$certfile\""
      }
      if {![file readable $keyfile]} {
        return -code error "cannot read KEY file \"$keyfile\""
      }
      package require tls
      tls::init -require no -request no -certfile $certfile -keyfile $keyfile
      set x [tls::socket -server $server $port]
      set type HTTPS
    } else {
      set x [socket -server $server $port]
    }
  }
  set coninfo [chan configure $x -sockname]
  set port [lindex $coninfo 2]
  if {$wappmode=="local"} {
    wappInt-start-browser http://127.0.0.1:$port/
  } elseif {$fromip!=""} {
    puts "Listening for $type requests on TCP port $port from IP $fromip"
  } else {
    puts "Listening for $type requests on TCP port $port"
  }
}


# Start up the wapp framework.  Parameters are a list passed as the
# single argument.
#
#    -server $PORT         Listen for HTTP requests on this TCP port $PORT
#
#    -local $PORT          Listen for HTTP requests on 127.0.0.1:$PORT
#
#    -scgi $PORT           Listen for SCGI requests on 127.0.0.1:$PORT
#
#    -remote-scgi $PORT    Listen for SCGI requests on TCP port $PORT
#
#    -cgi                  Handle a single CGI request
#
# To start a HTTPS server you must specify a certificate and a private key.
# (See tls::init for a detailed description.)
#
#    -certfile $FILENAME   Name of certificate file
#
#    -keyfile $FILENAME    Name of private key file
#
# With no arguments, the behavior is called "auto".  In "auto" mode,
# if the GATEWAY_INTERFACE environment variable indicates CGI, then run
# as CGI.  Otherwise, start an HTTP server bound to the loopback address
# only, on an arbitrary TCP port, and automatically launch a web browser
# on that TCP port.
#
# Additional options:
#
#    -fromip GLOB         Reject any incoming request where the remote
#                         IP address does not match the GLOB pattern.  This
#                         value defaults to '127.0.0.1' for -local and -scgi.
#
#    -nowait              Do not wait in the event loop.  Return immediately
#                         after all event handlers are established.
#
#    -trace               "puts" each request URL as it is handled, for
#                         debugging
#
#    -lint                Run wapp-safety-check on the application instead
#                         of running the application itself
#
#    -Dvar=value          Set TCL global variable "var" to "value"
#
#
proc wapp-start {arglist} {
  global env
  set mode auto
  set port 0
  set nowait 0
  set fromip {}
  set certfile {}
  set keyfile {}
  set n [llength $arglist]
  for {set i 0} {$i<$n} {incr i} {
    set term [lindex $arglist $i]
    if {[string match --* $term]} {set term [string range $term 1 end]}
    switch -glob -- $term {
      -server {
        incr i;
        set mode "server"
        set port [lindex $arglist $i]
      }
      -local {
        incr i;
        set mode "local"
        set fromip 127.0.0.1
        set port [lindex $arglist $i]
      }
      -scgi {
        incr i;
        set mode "scgi"
        set fromip 127.0.0.1
        set port [lindex $arglist $i]
      }
      -remote-scgi {
        incr i;
        set mode "remote-scgi"
        set port [lindex $arglist $i]
      }
      -cgi {
        set mode "cgi"
      }
      -fromip {
        incr i
        set fromip [lindex $arglist $i]
      }
      -nowait {
        set nowait 1
      }
      -trace {
        proc wappInt-trace {} {
          set q [wapp-param QUERY_STRING]
          set uri [wapp-param BASE_URL][wapp-param PATH_INFO]
          if {$q!=""} {append uri ?$q}
          puts $uri
        }
      }
      -lint {
        set res [wapp-safety-check]
        if {$res!=""} {
          puts "Potential problems in this code:"
          puts $res
          exit 1
        } else {
          exit
        }
      }
      -D*=* {
        if {[regexp {^.D([^=]+)=(.*)$} $term all var val]} {
          set ::$var $val
        }
      }
      -certfile {
        set certfile [lindex $arglist [incr i]]
      }
      -keyfile {
        set keyfile [lindex $arglist [incr i]]
      }
      default {
        error "unknown option: $term"
      }
    }
  }
  if {$mode=="auto"} {
    if {[info exists env(GATEWAY_INTERFACE)]
        && [string match CGI/1.* $env(GATEWAY_INTERFACE)]} {
      set mode cgi
    } else {
      set mode local
    }
  }
  if {$mode=="cgi"} {
    wappInt-handle-cgi-request
  } else {
    wappInt-start-listener $port $mode $fromip $certfile $keyfile
    if {!$nowait} {
      vwait ::forever
    }
  }
}