Skip to content

Commit 3aa49c5

Browse files
committed
Fix bugs in the libuv Web REPL rewrite
1 parent 1548425 commit 3aa49c5

File tree

3 files changed

+142
-124
lines changed

3 files changed

+142
-124
lines changed

ui/webserver/julia_web_base.jl

Lines changed: 78 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
# import the message types
1919
load("./ui/webserver/message_types.h")
2020

21-
#macro debug_only(x); x; end
22-
macro debug_only(x); end
21+
macro debug_only(x); x; end
22+
#macro debug_only(x); end
2323

2424
###########################################
2525
# set up the socket connection
@@ -114,8 +114,13 @@ function __socket_callback(client::TcpSocket,p::__PartialMessageBuffer,handle::P
114114
arr = ccall(:jl_pchar_to_array,Any,(Ptr,Int),base,nread)::Array{Uint8}
115115
@debug_only println("Callback: ",arr)
116116
pos = 0
117+
for b in arr
118+
print(b," ")
119+
end
120+
print("\n")
117121
while(pos<nread)
118122
pos+=1
123+
@debug_only println("loop at pos ",pos," of ",length(arr))
119124
b=arr[pos]
120125
if(p.current.msg_type == 255)
121126
p.current.msg_type = b
@@ -146,6 +151,7 @@ function __socket_callback(client::TcpSocket,p::__PartialMessageBuffer,handle::P
146151
break
147152
else
148153
append!(p.curArg.data,arr[pos:(pos+p.curArgLength-p.curArgPos)])
154+
@debug_only println("argument of length ",p.curArgLength," at pos ",p.curArgPos," complete");
149155
pos+=p.curArgLength-p.curArgPos;
150156
push(p.current.args,p.curArg)
151157
p.curArg=ASCIIString(Array(Uint8,0))
@@ -154,78 +160,79 @@ function __socket_callback(client::TcpSocket,p::__PartialMessageBuffer,handle::P
154160
println(p.num_args)
155161
println(p.current.args)
156162
end
163+
p.curArgLength=0
164+
p.curArgHeaderByteNum=0
165+
p.curArgPos=1
157166
if(numel(p.current.args)>=p.num_args)
158167
__msg=p.current
159168
p.current=__Message()
160169
p.num_args=255
161-
p.curArgLength=0
162-
p.curArgHeaderByteNum=0
163-
p.curArgPos=1
164-
165-
# MSG_INPUT_EVAL
166-
if __msg.msg_type == __MSG_INPUT_EVAL && length(__msg.args) == 3
167-
# parse the arguments
168-
__user_name = __msg.args[1]
169-
__user_id = __msg.args[2]
170-
__input = __msg.args[3]
171-
172-
# split the input into lines
173-
__lines = split(__input, '\n')
174-
175-
# try to parse each line incrementally
176-
__parsed_exprs = {}
177-
__input_so_far = ""
178-
__all_nothing = true
179-
180-
for i=1:length(__lines)
181-
# add the next line of input
182-
__input_so_far = strcat(__input_so_far, __lines[i], "\n")
183-
184-
# try to parse it
185-
__expr = parse_input_line(__input_so_far)
186-
187-
# if there was nothing to parse, just keep going
188-
if __expr == nothing
189-
continue
190-
end
191-
__all_nothing = false
192-
__expr_multitoken = isa(__expr, Expr)
193-
194-
# stop now if there was a parsing error
195-
if __expr_multitoken && __expr.head == :error
196-
# send everyone the input
197-
__write_message(client,__Message(__MSG_OUTPUT_EVAL_INPUT, {__user_id, __user_name, __input}))
198-
return __write_message(client,__Message(__MSG_OUTPUT_EVAL_ERROR, {__user_id, __expr.args[1]}))
199-
end
200-
201-
# if the expression was incomplete, just keep going
202-
if __expr_multitoken && __expr.head == :continue
203-
continue
204-
end
205-
206-
# add the parsed expression to the list
207-
__input_so_far = ""
208-
__parsed_exprs = [__parsed_exprs, {(__user_id, __expr)}]
209-
end
210-
211-
# if the input was empty, stop early
212-
if __all_nothing
213-
# send everyone the input
214-
__write_message(client,__Message(__MSG_OUTPUT_EVAL_INPUT, {__user_id, __user_name, __input}))
215-
return __write_message(client,__Message(__MSG_OUTPUT_EVAL_RESULT, {__user_id, ""}))
216-
end
217-
218-
# tell the browser if we didn't get a complete expression
219-
if length(__parsed_exprs) == 0
220-
return __write_message(client,__Message(__MSG_OUTPUT_EVAL_INCOMPLETE, {__user_id}))
221-
end
222-
223-
# send everyone the input
224-
__write_message(client,__Message(__MSG_OUTPUT_EVAL_INPUT, {__user_id, __user_name, __input}))
225-
226-
__eval_exprs(client, __parsed_exprs)
227-
end
228-
end
170+
171+
# MSG_INPUT_EVAL
172+
if __msg.msg_type == __MSG_INPUT_EVAL && length(__msg.args) == 3
173+
@debug_only println("Evaluating input")
174+
# parse the arguments
175+
__user_name = __msg.args[1]
176+
__user_id = __msg.args[2]
177+
__input = __msg.args[3]
178+
179+
# split the input into lines
180+
__lines = split(__input, '\n')
181+
182+
# try to parse each line incrementally
183+
__parsed_exprs = {}
184+
__input_so_far = ""
185+
__all_nothing = true
186+
187+
for i=1:length(__lines)
188+
# add the next line of input
189+
__input_so_far = strcat(__input_so_far, __lines[i], "\n")
190+
191+
# try to parse it
192+
__expr = parse_input_line(__input_so_far)
193+
194+
# if there was nothing to parse, just keep going
195+
if __expr == nothing
196+
continue
197+
end
198+
__all_nothing = false
199+
__expr_multitoken = isa(__expr, Expr)
200+
201+
# stop now if there was a parsing error
202+
if __expr_multitoken && __expr.head == :error
203+
# send everyone the input
204+
__write_message(client,__Message(__MSG_OUTPUT_EVAL_INPUT, {__user_id, __user_name, __input}))
205+
return __write_message(client,__Message(__MSG_OUTPUT_EVAL_ERROR, {__user_id, __expr.args[1]}))
206+
end
207+
208+
# if the expression was incomplete, just keep going
209+
if __expr_multitoken && __expr.head == :continue
210+
continue
211+
end
212+
213+
# add the parsed expression to the list
214+
__input_so_far = ""
215+
__parsed_exprs = [__parsed_exprs, {(__user_id, __expr)}]
216+
end
217+
218+
# if the input was empty, stop early
219+
if __all_nothing
220+
# send everyone the input
221+
__write_message(client,__Message(__MSG_OUTPUT_EVAL_INPUT, {__user_id, __user_name, __input}))
222+
return __write_message(client,__Message(__MSG_OUTPUT_EVAL_RESULT, {__user_id, ""}))
223+
end
224+
225+
# tell the browser if we didn't get a complete expression
226+
if length(__parsed_exprs) == 0
227+
return __write_message(client,__Message(__MSG_OUTPUT_EVAL_INCOMPLETE, {__user_id}))
228+
end
229+
230+
# send everyone the input
231+
__write_message(client,__Message(__MSG_OUTPUT_EVAL_INPUT, {__user_id, __user_name, __input}))
232+
233+
__eval_exprs(client, __parsed_exprs)
234+
end
235+
end
229236
end
230237
end
231238
end
@@ -262,4 +269,4 @@ catch(err)
262269
set_current_output_stream(STDERR)
263270
print(err)
264271
end
265-
end
272+
end

ui/webserver/server.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -206,21 +206,23 @@ bool scgi::request::get_field_exists(string name)
206206
namespace scgi
207207
{
208208

209-
#define PASS_ON(f) stream->read_cb = &f; \
210-
uv_buf_t buf2; \
211-
buf2.base=pos; \
212-
buf2.len=buf.len-i; \
213-
f(stream,nread-i,buf2);
209+
#define PASS_ON(f) stream->read_cb = &f; \
210+
uv_buf_t buf2; \
211+
buf2.base=pos; \
212+
buf2.len=buf.len-nread-(pos-buf.base); \
213+
f(stream,nread-(pos-buf.base),buf2);
214214

215215
void read_body(uv_stream_t* stream, ssize_t nread, uv_buf_t buf)
216216
{
217217
reading_in_progress *p = (reading_in_progress*)(stream->data);
218-
if(p->isComma)
218+
if(p->isComma) {
219219
buf.base=buf.base+2;
220+
nread-=2;
221+
}
220222
if(p->bufBase==0) p->bufBase=buf.base;
221-
if(p->body_length>p->pos+buf.len) {
222-
p->body+=buf.base;
223-
p->pos+=buf.len;
223+
if(p->body_length>p->pos+nread) {
224+
p->body.append(buf.base,nread);
225+
p->pos+=nread;
224226
} else {
225227
p->body.append(buf.base,p->body_length-p->pos);
226228
//do the actual processing
@@ -487,7 +489,10 @@ void read_header(uv_stream_t* stream, ssize_t nread, uv_buf_t buf)
487489
reading_in_progress *p = (reading_in_progress*)(stream->data);
488490
if(p->bufBase==0)p->bufBase=buf.base;
489491
int i;
490-
if(p->isComma) (++(p->pos),++pos);
492+
if(p->isComma) {
493+
(++(p->pos),++pos);
494+
p->isComma=false;
495+
}
491496
for(i=0; i<buf.len&&p->pos<p->header_length; ++i, ++pos, ++p->pos)
492497
{
493498
if(p->inName) {
@@ -513,6 +518,8 @@ void read_header(uv_stream_t* stream, ssize_t nread, uv_buf_t buf)
513518
}
514519
}
515520
}
521+
if(p->current_header.name!="")
522+
p->header_list.push_back(p->current_header);
516523
if(p->pos>=p->header_length) {
517524
//process cookies
518525
for (size_t j = 0; j < p->header_list.size(); j++)

0 commit comments

Comments
 (0)