@@ -9,6 +9,7 @@ const TRANSPORT = { http, https, ws: http, wss: https };
9
9
10
10
const MIME_TYPES = {
11
11
html : 'text/html; charset=UTF-8' ,
12
+ json : 'application/json; charset=UTF-8' ,
12
13
js : 'application/javascript; charset=UTF-8' ,
13
14
css : 'text/css' ,
14
15
png : 'image/png' ,
@@ -64,82 +65,58 @@ class Client {
64
65
else this . error ( 404 ) ;
65
66
}
66
67
67
- error ( status ) {
68
- if ( this . res . finished ) return ;
69
- this . res . writeHead ( status , { 'Content-Type' : 'text/plain' } ) ;
70
- this . res . end ( `HTTP ${ status } : ${ http . STATUS_CODES [ status ] } ` ) ;
71
- }
72
-
73
- async apihttp ( method , args ) {
74
- const { res, application } = this ;
75
- const { semaphore } = application . server ;
76
- try {
77
- await semaphore . enter ( ) ;
78
- } catch {
79
- this . error ( 504 ) ;
68
+ error ( status , err ) {
69
+ const { application, req, res, connection } = this ;
70
+ const reason = http . STATUS_CODES [ status ] ;
71
+ const message = err ? err . stack : reason ;
72
+ application . logger . error ( `${ req . url } - ${ message } - ${ status } ` ) ;
73
+ const result = JSON . stringify ( { result : 'error' , reason } ) ;
74
+ if ( connection ) {
75
+ connection . send ( result ) ;
80
76
return ;
81
77
}
82
- const session = await this . application . auth . restore ( this ) ;
83
- const sandbox = session ? session . sandbox : undefined ;
84
- const context = session ? session . context : { } ;
85
- try {
86
- const exp = this . application . runScript ( method , sandbox ) ;
87
- const proc = exp ( context ) ;
88
- if ( ! session && proc . access !== 'public' ) {
89
- this . application . logger . error ( `Forbidden ${ method } ` ) ;
90
- this . error ( 403 ) ;
91
- semaphore . leave ( ) ;
92
- return ;
93
- }
94
- const result = await proc . method ( args ) ;
95
- if ( res . finished ) {
96
- semaphore . leave ( ) ;
97
- return ;
98
- }
99
- if ( ! session && proc . access === 'public' ) {
100
- this . application . auth . start ( this , result . userId ) ;
101
- }
102
- res . end ( JSON . stringify ( result ) ) ;
103
- } catch ( err ) {
104
- this . application . logger . error ( err . stack ) ;
105
- this . error ( err . message === 'Not found' ? 404 : 500 ) ;
106
- }
107
- semaphore . leave ( ) ;
78
+ if ( res . finished ) return ;
79
+ res . writeHead ( status , { 'Content-Type' : MIME_TYPES . json } ) ;
80
+ res . end ( result ) ;
108
81
}
109
82
110
- async apiws ( method , args ) {
111
- const { connection , application } = this ;
83
+ async execute ( method , args ) {
84
+ const { application } = this ;
112
85
const { semaphore } = application . server ;
113
- const send = obj => connection . send ( JSON . stringify ( obj ) ) ;
114
- try {
115
- await semaphore . enter ( ) ;
116
- } catch {
117
- send ( { result : 'error' , reason : 'timeout' } ) ;
118
- return ;
119
- }
86
+ await semaphore . enter ( ) ;
120
87
try {
121
88
const session = await application . auth . restore ( this ) ;
122
89
const sandbox = session ? session . sandbox : undefined ;
123
90
const context = session ? session . context : { } ;
124
91
const exp = application . runScript ( method , sandbox ) ;
125
92
const proc = exp ( context ) ;
126
93
if ( ! session && proc . access !== 'public' ) {
127
- application . logger . error ( `Forbidden: ${ method } ` ) ;
128
- send ( { result : 'error' , reason : 'forbidden' } ) ;
129
94
semaphore . leave ( ) ;
130
- return ;
95
+ throw new Error ( `Forbidden: ${ method } ` ) ;
131
96
}
132
97
const result = await proc . method ( args ) ;
133
98
if ( ! session && proc . access === 'public' ) {
134
99
const session = application . auth . start ( this , result . userId ) ;
135
100
result . token = session . token ;
136
101
}
137
- send ( result ) ;
102
+ return JSON . stringify ( result ) ;
103
+ } finally {
104
+ semaphore . leave ( ) ;
105
+ }
106
+ }
107
+
108
+ async rpc ( method , args ) {
109
+ const { res, connection } = this ;
110
+ try {
111
+ const result = await this . execute ( method , args ) ;
112
+ if ( connection ) connection . send ( result ) ;
113
+ else res . end ( result ) ;
138
114
} catch ( err ) {
139
- application . logger . error ( err . stack ) ;
140
- send ( { result : 'error' } ) ;
115
+ if ( err . message === 'Not found' ) this . error ( 404 ) ;
116
+ else if ( err . message === 'Semaphore timeout' ) this . error ( 504 ) ;
117
+ else if ( err . message . startsWith ( 'Forbidden:' ) ) this . error ( 403 ) ;
118
+ else this . error ( 500 , err ) ;
141
119
}
142
- semaphore . leave ( ) ;
143
120
}
144
121
}
145
122
@@ -171,14 +148,13 @@ const listener = application => (req, res) => {
171
148
}
172
149
receiveArgs ( req ) . then ( args => {
173
150
const method = url . substring ( METHOD_OFFSET ) ;
174
- client . apihttp ( method , args ) ;
151
+ client . rpc ( method , args ) ;
175
152
} ) ;
176
153
} else {
177
154
client . static ( ) ;
178
155
}
179
156
} ;
180
157
181
-
182
158
class Server {
183
159
constructor ( config , application ) {
184
160
this . config = config ;
@@ -196,7 +172,7 @@ class Server {
196
172
const client = new Client ( req , null , application , connection ) ;
197
173
connection . on ( 'message' , message => {
198
174
const { method, args } = JSON . parse ( message ) ;
199
- client . apiws ( method , args ) ;
175
+ client . rpc ( method , args ) ;
200
176
} ) ;
201
177
} ) ;
202
178
}
0 commit comments