Wapp

Diff
Login

Differences From Artifact [d6752a9691]:

To Artifact [0375d6bb34]:


161
162
163
164
165
166
167



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184



















185
186
187
188
189
190
191






192
193
194

195
196
197
198
199
200
201
202
203
204
205
206







207
208
209
210
211
212
213
161
162
163
164
165
166
167
168
169
170

















171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189







190
191
192
193
194
195



196












197
198
199
200
201
202
203
204
205
206
207
208
209
210







+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+







  if {[catch [list wappInt-readable-unsafe $chan] msg]} {
    puts stderr "$msg\n$::errorInfo"
    wappInt-close-channel $chan
  }
}
proc wappInt-readable-unsafe {chan} {
  upvar #0 wappInt-$chan W
  if {![dict exists $W .toread]} {
    # If the .toread key is not set, that means we are still reading
    # the header
  set line [string trimright [gets $chan]]
  set n [string length $line]
  if {$n>0} {
    if {[dict get $W .header]=="" || [regexp {^\s+} $line]} {
      dict append W .header $line
    } else {
      dict append W .header \n$line
    }
    if {[string length [dict get $W .header]]>100000} {
      error "HTTP request header too big - possible DOS attack"
    }
  } elseif {$n==0} {
    wappInt-parse-header $chan
    if {[dict get $W REQUEST_METHOD]=="POST"
           && [dict exists $W hdr.CONTENT-LENGTH]
           && [string is integer -strict [dict get $W hdr.CONTENT-LENGTH]]} {
      dict set W .toread [dict get $W hdr.CONTENT-LENGTH]
    set line [string trimright [gets $chan]]
    set n [string length $line]
    if {$n>0} {
      if {[dict get $W .header]=="" || [regexp {^\s+} $line]} {
        dict append W .header $line
      } else {
        dict append W .header \n$line
      }
      if {[string length [dict get $W .header]]>100000} {
        error "HTTP request header too big - possible DOS attack"
      }
    } elseif {$n==0} {
      wappInt-parse-header $chan
      set len 0
      if {[dict exists $W .hdr:CONTENT-LENGTH]} {
        set len [dict get $W .hdr:CONTENT-LENGTH]
      }
      if {$len>0} {
        dict set W .toread $len
      fileevent $chan readable [list wappInt-read-post-data $chan]
    } else {
      wappInt-handle-request $chan
    }
  }
}

      } else {
        wappInt-handle-request $chan
      }
    }
  } else {
    # If .toread is set, that means we are reading the query content.
# Read in as much of the POST data as we can
#
proc wappInt-read-post-data {chan} {
    # Continue reading until .toread reaches zero.
  if {[catch [list wappInt-read-post-data-unsafe $chan]]} {
    wappInt-close-channel $chan
  }
}
proc wappInt-read-post-data-unsafe {chan} {
  upvar #0 wappInt-$chan W
  set got [read $chan [dict get $W .toread]]
  dict append W .post $got
  dict set W .toread [expr {[dict get $W .toread]-[string length $got]}]
  if {[dict get $W .toread]<=0} {
    wappInt-parse-post-data $chan
    wappInt-handle-request $chan
    set got [read $chan [dict get $W .toread]]
    dict append W .post $got
    dict set W .toread [expr {[dict get $W .toread]-[string length $got]}]
    if {[dict get $W .toread]<=0} {
      wappInt-parse-post-data $chan
      wappInt-handle-request $chan
    }
  }
}

# Decode the HTTP request header.
#
# This routine is always running inside of a [catch], so if
# any problems arise, simply raise an error.
302
303
304
305
306
307
308


















299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
      $str {[encoding convertfrom utf-8 [DecodeHex \1\2\3]]} str
  regsub -all -- \
      {%([CDcd][A-Fa-f0-9])%([89ABab][A-Fa-f0-9])}                     \
      $str {[encoding convertfrom utf-8 [DecodeHex \1\2]]} str
  regsub -all -- {%([0-7][A-Fa-f0-9])} $str {\\u00\1} str
  return [subst -novar $str]
}

# Process POST data
#
proc wappInt-parse-post-data {chan} {
  upvar #0 wappInt-$chan W
  if {[dict exists $W .hdr:CONTENT-TYPE]
      && [dict get $W .hdr:CONTENT-TYPE]=="application/x-www-form-urlencoded"} {
    foreach qterm [split [string trim [dict get $W .post]] &] {
      set qsplit [split $qterm =]
      set nm [lindex $qsplit 0]
      if {[regexp {^[a-z][a-z0-9]*$} $nm]} {
        dict set W $nm [wappInt-url-decode [lindex $qsplit 1]]
      }
    }
    return
  }
  # TODO: Decode multipart/form-data
}