@@ -917,6 +917,193 @@ task_t* anet_async_http_stream(anet_async_http_request_t *req,
917917 return t ;
918918}
919919
920+ /* ============================================================
921+ * 通用二进制流读取 (raw stream) 实现
922+ * ============================================================ */
923+
924+ typedef struct {
925+ const char * method ;
926+ const char * host ;
927+ uint16_t port ;
928+ int use_tls ;
929+ const char * path ;
930+ const char * * headers ;
931+ const char * body ;
932+ anet_http_chunk_cb_t on_chunk ;
933+ void * userdata ;
934+
935+ anet_palsock_t sock ;
936+ anet_socket_t * async_sock ;
937+ async_ssl_t * async_ssl ;
938+ anet_stream_t * stream ;
939+ char * request ;
940+
941+ // header 跳过状态: 累积响应头直到 \r\n\r\n, 之后 body 字节直接透传。
942+ char * hdrbuf ;
943+ size_t hdrbuf_len ;
944+ size_t hdrbuf_cap ;
945+ int header_done ;
946+ } raw_stream_internal_t ;
947+
948+ static void raw_emit_bridge (void * item , void * userdata ) {
949+ raw_stream_internal_t * st = (raw_stream_internal_t * )userdata ;
950+ if (st -> on_chunk ) {
951+ st -> on_chunk ((const anet_http_chunk_t * )item , st -> userdata );
952+ }
953+ }
954+
955+ // 往 header 缓冲追加一段字节, 保持 NUL 结尾 (供 strstr 找 \r\n\r\n)。失败返回 -1。
956+ static int raw_hdr_push (raw_stream_internal_t * st , const char * p , size_t n ) {
957+ if (st -> hdrbuf_len + n + 1 > st -> hdrbuf_cap ) {
958+ size_t ncap = st -> hdrbuf_cap ? st -> hdrbuf_cap * 2 : 1024 ;
959+ while (ncap < st -> hdrbuf_len + n + 1 ) ncap *= 2 ;
960+ char * nb = realloc (st -> hdrbuf , ncap );
961+ if (!nb ) return -1 ;
962+ st -> hdrbuf = nb ;
963+ st -> hdrbuf_cap = ncap ;
964+ }
965+ memcpy (st -> hdrbuf + st -> hdrbuf_len , p , n );
966+ st -> hdrbuf_len += n ;
967+ st -> hdrbuf [st -> hdrbuf_len ] = '\0' ;
968+ return 0 ;
969+ }
970+
971+ task_t * task_arg (anet_async_http_stream_raw_ ) {
972+ gen_dec_vars (
973+ raw_stream_internal_t * st ;
974+ future_t * fut ;
975+ future_t * resolve_fut ;
976+ task_t * task ;
977+ struct sockaddr_storage addr ;
978+ int addr_len ;
979+ char buffer [HTTP_BUFFER_SIZE ];
980+ int bytes_read ;
981+ anet_http_chunk_t chunk ; /* 跨 gen_emit 存活 */
982+ );
983+ gen_begin (ctx );
984+
985+ {
986+ /* 顶层驱动: arg 为 NULL, 从 userdata 取参数 (同 SSE, 见 gen_emit 约束)。 */
987+ gen_var (st ) = (raw_stream_internal_t * )gen_userdata ();
988+ gen_var (st )-> sock = -1 ;
989+ }
990+
991+ gen_var (resolve_fut ) = anet_palsock_resolve_async (gen_var (st )-> host , AF_UNSPEC );
992+ if (!gen_var (resolve_fut )) { gen_return (anet_res_status (ANET_ERR )); }
993+ gen_yield (gen_var (resolve_fut ));
994+ {
995+ anet_resolve_result_t * r = (anet_resolve_result_t * )future_result (gen_var (resolve_fut ));
996+ if (!r || r -> ok != 0 ) { free (r ); gen_return (anet_res_status (ANET_ERR )); }
997+ gen_var (addr ) = r -> addr ;
998+ gen_var (addr_len ) = r -> addr_len ;
999+ free (r );
1000+ }
1001+ if (gen_var (addr ).ss_family == AF_INET ) {
1002+ ((struct sockaddr_in * )& gen_var (addr ))-> sin_port = htons (gen_var (st )-> port );
1003+ } else if (gen_var (addr ).ss_family == AF_INET6 ) {
1004+ ((struct sockaddr_in6 * )& gen_var (addr ))-> sin6_port = htons (gen_var (st )-> port );
1005+ }
1006+
1007+ gen_var (st )-> sock = anet_palsock_create (gen_var (addr ).ss_family , SOCK_STREAM , 0 , 1 );
1008+ if (!anet_palsock_is_valid (gen_var (st )-> sock )) { gen_return (anet_res_status (ANET_ERR )); }
1009+ gen_var (st )-> async_sock = anet_socket_create (gen_var (st )-> sock );
1010+ if (!gen_var (st )-> async_sock ) { gen_return (anet_res_status (ANET_ERR )); }
1011+ gen_var (fut ) = anet_socket_connect (gen_var (st )-> async_sock , (struct sockaddr * )& gen_var (addr ), gen_var (addr_len ));
1012+ gen_yield (gen_var (fut ));
1013+ if (future_is_rejected (gen_var (fut ))) { gen_return (anet_res_status (ANET_ERR )); }
1014+ if (gen_var (st )-> use_tls ) {
1015+ gen_var (st )-> async_ssl = async_ssl_create (ASYNC_SSL_CLIENT , gen_var (st )-> host );
1016+ if (!gen_var (st )-> async_ssl ) { gen_return (anet_res_status (ANET_ERR )); }
1017+ async_ssl_attach_socket (gen_var (st )-> async_ssl , gen_var (st )-> async_sock );
1018+ gen_var (task ) = async_ssl_handshake (gen_var (st )-> async_ssl );
1019+ gen_yield_from_task (gen_var (task ));
1020+ if (anet_code_of (future_result (gen_var (task )-> future )) != 0 ) { gen_return (anet_res_status (ANET_ERR )); }
1021+ gen_var (st )-> stream = anet_stream_from_ssl (gen_var (st )-> async_ssl );
1022+ } else {
1023+ gen_var (st )-> stream = anet_stream_from_socket (gen_var (st )-> async_sock );
1024+ }
1025+ if (!gen_var (st )-> stream ) { gen_return (anet_res_status (ANET_ERR )); }
1026+
1027+ gen_var (st )-> request = create_request_string (
1028+ gen_var (st )-> method , gen_var (st )-> host , gen_var (st )-> port ,
1029+ gen_var (st )-> path , gen_var (st )-> headers , gen_var (st )-> body );
1030+ if (!gen_var (st )-> request ) { gen_return (anet_res_status (ANET_ERR )); }
1031+ gen_var (task ) = anet_stream_write_all (gen_var (st )-> stream , gen_var (st )-> request , strlen (gen_var (st )-> request ));
1032+ gen_yield_from_task (gen_var (task ));
1033+ if (anet_code_of (future_result (gen_var (task )-> future )) != 0 ) { gen_return (anet_res_status (ANET_ERR )); }
1034+ free (gen_var (st )-> request );
1035+ gen_var (st )-> request = NULL ;
1036+
1037+ // 读取: 先攒 header 到 \r\n\r\n, 之后 body 字节整块 emit。
1038+ while (1 ) {
1039+ gen_var (task ) = anet_stream_read (gen_var (st )-> stream , sizeof (gen_var (buffer )), gen_var (buffer ));
1040+ gen_yield_from_task (gen_var (task ));
1041+ gen_var (bytes_read ) = (int )anet_code_of (future_result (gen_var (task )-> future ));
1042+ if (gen_var (bytes_read ) <= 0 ) {
1043+ gen_return (anet_res_status (ANET_OK )); // 流结束
1044+ }
1045+
1046+ if (gen_var (st )-> header_done ) {
1047+ gen_var (chunk ).data = gen_var (buffer );
1048+ gen_var (chunk ).len = (size_t )gen_var (bytes_read );
1049+ gen_emit (& gen_var (chunk ));
1050+ } else {
1051+ if (raw_hdr_push (gen_var (st ), gen_var (buffer ), (size_t )gen_var (bytes_read )) != 0 ) {
1052+ gen_return (anet_res_status (ANET_ERR ));
1053+ }
1054+ char * he = strstr (gen_var (st )-> hdrbuf , "\r\n\r\n" );
1055+ if (he ) {
1056+ gen_var (st )-> header_done = 1 ;
1057+ size_t body_off = (size_t )((he + 4 ) - gen_var (st )-> hdrbuf );
1058+ if (gen_var (st )-> hdrbuf_len > body_off ) {
1059+ gen_var (chunk ).data = gen_var (st )-> hdrbuf + body_off ;
1060+ gen_var (chunk ).len = gen_var (st )-> hdrbuf_len - body_off ;
1061+ gen_emit (& gen_var (chunk ));
1062+ }
1063+ }
1064+ }
1065+ }
1066+
1067+ gen_cleanup ();
1068+ if (gen_var (st )) {
1069+ free (gen_var (st )-> request );
1070+ free (gen_var (st )-> hdrbuf );
1071+ free (gen_var (st )-> stream );
1072+ if (gen_var (st )-> async_ssl ) {
1073+ async_ssl_destroy (gen_var (st )-> async_ssl );
1074+ } else if (gen_var (st )-> async_sock ) {
1075+ anet_socket_close (gen_var (st )-> async_sock );
1076+ free (gen_var (st )-> async_sock );
1077+ } else if (anet_palsock_is_valid (gen_var (st )-> sock )) {
1078+ anet_palsock_close (gen_var (st )-> sock );
1079+ }
1080+ free (gen_var (st ));
1081+ gen_var (st ) = NULL ;
1082+ }
1083+ gen_end (NULL );
1084+ }
1085+
1086+ task_t * anet_async_http_stream_raw (anet_async_http_request_t * req ,
1087+ anet_http_chunk_cb_t on_chunk , void * userdata ) {
1088+ if (!req ) return NULL ;
1089+ raw_stream_internal_t * st = calloc (1 , sizeof (* st ));
1090+ if (!st ) return NULL ;
1091+ st -> method = req -> method ;
1092+ st -> host = req -> host ;
1093+ st -> port = req -> port ;
1094+ st -> use_tls = req -> use_tls ;
1095+ st -> path = req -> path ;
1096+ st -> headers = req -> headers ;
1097+ st -> body = req -> body ;
1098+ st -> on_chunk = on_chunk ;
1099+ st -> userdata = userdata ;
1100+
1101+ task_t * t = anet_async_http_stream_raw_ (st );
1102+ if (!t ) { free (st ); return NULL ; }
1103+ task_set_on_emit (t , raw_emit_bridge , st );
1104+ return t ;
1105+ }
1106+
9201107// 简化的异步GET请求
9211108task_t * task_arg (anet_async_http_get_ ) {
9221109 gen_dec_vars (
0 commit comments