123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116openCoretypet={mutablepartial_content:(read_write,Iobuf.seek)Iobuf.t;content_handler:(read,Iobuf.no_seek)Iobuf.t->unit;ping_handler:content:(read,Iobuf.no_seek)Iobuf.t->unit;close_handler:code:Connection_close_reason.t->reason:string->partial_content:stringoption->unit;protocol_error_handler:reason:string->partial_content:stringoption->frame:Frame.toption->unit}letpartial_content_statust=matchIobuf.length_lot.partial_content=0with|false->`Has_partial_content|true->`No_partial_content;;letpartial_content_stringt=matchpartial_content_statustwith|`No_partial_content->None|`Has_partial_content->Iobuf.flip_lot.partial_content;letpartial_content=Iobuf.to_stringt.partial_contentinIobuf.flip_hit.partial_content;Somepartial_content;;letclear_partial_contentt=Iobuf.resett.partial_contentletfinalise_contentt=letpartial_content=partial_content_stringtinclear_partial_contentt;partial_content;;letcreate~content_handler~ping_handler~close_handler~protocol_error_handler?(initial_buffer_size=8192)()=letpartial_content=Iobuf.create~len:initial_buffer_sizein{content_handler;partial_content;ping_handler;close_handler;protocol_error_handler};;letappend_contentt(content:(read,Iobuf.no_seek)Iobuf.t)=letcontent_len=Iobuf.lengthcontentinletavailable_len=Iobuf.lengtht.partial_contentinlethas_enough_space=available_len>=content_leninifnothas_enough_spacethen(letold_capacity=Iobuf.capacityt.partial_contentinletnew_len=2*(old_capacity+content_len)inletnew_iobuf=Iobuf.create~len:new_leninIobuf.flip_lot.partial_content;Iobuf.Blit_consume_and_fill.blito~src:t.partial_content~dst:new_iobuf();t.partial_content<-new_iobuf);Iobuf.Blit_fill.blito~src:content~dst:t.partial_content();;letprocess_framet~(opcode:Opcode.t)~(final:bool)~(content:(read,Iobuf.no_seek)Iobuf.t)=matchopcodewith|Close->Iobuf.protect_window_bounds_and_buffercontent~f:(funcontent->letcode=ifIobuf.lengthcontent>=2thenConnection_close_reason.of_int(Iobuf.Consume.int16_becontent)elseUnknown0inletreason=Iobuf.Consume.stringocontentint.close_handler~code~reason~partial_content:None)|Ping->t.ping_handler~content|Pong|Ctrl(_:int)->()|Text|Binary|Nonctrl(_:int)->(matchpartial_content_statust,finalwith|`No_partial_content,true->t.content_handlercontent|`No_partial_content,false->append_contenttcontent|`Has_partial_content,(true|false)->t.protocol_error_handler~reason:"Bad frame in the middle of a fragmented message: Expecting control or \
continuation frame"~partial_content:(finalise_contentt)~frame:(Some{opcode;final;content=Iobuf.to_stringcontent}))|Continuation->(matchpartial_content_statust,finalwith|`No_partial_content,(true|false)->t.protocol_error_handler~reason:"Received continuation message without a previous non-control frame to \
continue."~partial_content:None~frame:(Some{opcode;final;content=Iobuf.to_stringcontent})|`Has_partial_content,false->append_contentt(Iobuf.no_seekcontent)|`Has_partial_content,true->append_contentt(Iobuf.no_seekcontent);Iobuf.flip_lot.partial_content;t.content_handler(Iobuf.read_only(Iobuf.no_seekt.partial_content));clear_partial_contentt);;