aboutsummaryrefslogtreecommitdiff
path: root/elymas/lib/net/alg/http.ey
blob: 48b851ffda19b798fec1f4adc86b96b6276a9b3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# provide a http server
{ <
  net .alg .bufferedEpollServer "^" via

  <
    { "request unconfigured (of rawHttpServer)" die } /request deffst
    { 4096 } /inputBufferLimit deffst

    { = }' /set deffst
    { scope keys }' /setters deffst
    { _ ^settings .installSetters =*install 
      setters { _ { set }_ -01 install }" each
    } /installSetters deffst
  > _ ==settings "::" via

  { -10 deffst }' ::installSetters

  { ":" via "" ==url "" ==method < { defvst }' /put deffst > ==headers "" ==body
    {
      method url headers body < ==body ==headers ==url ==method
        [ ] ==outputHeaders
        { :close } =*close
        { :write } =*write
        { :finish } =*finish
        { ==contentType
          "HTTP/1.0 200 Ok\r\nContent-Type: " contentType cat "\r\n" cat
          outputHeaders |cat each
          "\r\n" cat -01 cat :write :finish
        } =*ok
        { ==contentType
          "HTTP/1.0 500 Error\r\nContent-Type: " contentType cat "\r\n" cat
          outputHeaders |cat each
          "\r\n" cat -01 cat :write :finish
        } =*fail
        { [ -01 "\r\n" cat ] outputHeaders -01 cat =outputHeaders } =*addHeader
      > ::request
    } =*requestParsed

    <
      { :close } _ =*err =*end
      { ==inBuffer
        { inBuffer "\n" regex } { [
          { inBuffer len ::inputBufferLimit gt } { "" =inBuffer :close }
          { inBuffer "^(GET|POST) ([^\r\n]*) HTTP/\\d\\.\\d\r?\n(.*)" regex } { =method =url =inBuffer }
          { inBuffer "^([^:\r\n]+): ([^\r\n]*)\r?\n(.*)" regex } { headers .put =inBuffer }
          { inBuffer "^\r?\n(.*)" regex } { =inBuffer
            headers .?Content-Length not {
              requestParsed
            } {
              headers .Content-Length txt .consume .u ==contentLength

              # FIXME: Must change *=in and =*end here to correctly process further incoming data
              { body -01 cat =body
                body len _ ::inputBufferLimit gt { "" =body :close } rep
                           contentLength eq { requestParsed } rep
                ""
              } =in

              inBuffer in =inBuffer
            } ? *
          }
          { 1 } {
            "HTTP/1.0 400 Error\r\nContent-Type: text/html\r\n\r\n<html><body>Could not parse request</body></html>\r\n"
            :write :finish "" =inBuffer
          }
        ] conds } loop inBuffer } =*in
    >
  } ^accept

  {
    { ^run } {
      _ .?close { .close } { ??!' } ? *
    } ?!io.net
  } /run deffst
> } /rawHttpServer net .alg .deff

{ <
  net .alg .rawHttpServer "^" via ^settings "::" via

  <
    { "request unconfigured (of httpServer)" die } /request deffst

    { = }' /set deffst
    { scope keys }' /setters deffst
    { _ ^settings .installSetters =*install 
      setters { _ { set }_ -01 install }" each
    } /installSetters deffst
  > _ ==settings "::" via

  { -10 deffst }' ::installSetters

  { _ ==req ":" via
    < { defvst }' > ==args { net .alg .uri .percentEncoding .|consume -30*20*1* }_ =*setArg
    :url _ ==url
           "^([^?]*)\\?(.*)$" regex {
             =url "&" str .split { _ ==arg
               "^([^=]*)=(.*)$" regex not { "" arg } rep
               setArg
             } each
           } rep

    url args < ==args ==url req >' ::request
  } ^request

  { ^run } /run deffst
> } /httpServer net .alg .deff

# vim: syn=elymas