123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107(*----------------------------------------------------------------------------
* Copyright (c) 2018 Inhabited Type LLC.
* Copyright (c) 2021 António Nuno Monteiro
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*----------------------------------------------------------------------------*)moduleHttpaf=Dream_httpaf_.HttpafmoduleIOVec=Httpaf.IOVectypet={faraday:Faraday.t;mutableread_scheduled:bool;mutableon_eof:unit->unit;mutableon_read:Bigstringaf.t->off:int->len:int->unit}letdefault_on_eof=Sys.opaque_identity(fun()->())letdefault_on_read=Sys.opaque_identity(fun_~off:_~len:_->())letof_faradayfaraday={faraday;read_scheduled=false;on_eof=default_on_eof;on_read=default_on_read}letcreatebuffer=of_faraday(Faraday.of_bigstringbuffer)letcreate_empty()=lett=createBigstringaf.emptyinFaraday.closet.faraday;tletempty=create_empty()letis_closedt=Faraday.is_closedt.faradayletunsafe_faradayt=t.faradayletrecdo_execute_readton_eofon_read=matchFaraday.operationt.faradaywith|`Yield->()|`Close->t.read_scheduled<-false;t.on_eof<-default_on_eof;t.on_read<-default_on_read;on_eof()|`Writev[]->assertfalse|`Writev(iovec::_)->t.read_scheduled<-false;t.on_eof<-default_on_eof;t.on_read<-default_on_read;let{IOVec.buffer;off;len}=iovecinFaraday.shiftt.faradaylen;on_readbuffer~off~len;execute_readtandexecute_readt=ift.read_scheduledthendo_execute_readtt.on_eoft.on_readletschedule_readt~on_eof~on_read=ift.read_scheduledthenfailwith"Payload.schedule_read: reader already scheduled";ifnot(is_closedt)thenbegint.read_scheduled<-true;t.on_eof<-on_eof;t.on_read<-on_read;end;do_execute_readton_eofon_readletis_read_scheduledt=t.read_scheduledletcloset=Faraday.closet.faraday;execute_readt