Net-HTTP2-nghttp2

 view release on metacpan or  search on metacpan

nghttp2.c  view on Meta::CPAN

/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.51 from the
 * contents of nghttp2.xs. Do not edit this file, edit nghttp2.xs instead.
 *
 *    ANY CHANGES MADE HERE WILL BE LOST!
 *
 */

#line 1 "nghttp2.xs"
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include <nghttp2/nghttp2.h>
#include <string.h>

/*
 * Net::HTTP2::nghttp2 - Perl XS bindings for nghttp2
 *
 * This module provides server-side HTTP/2 support via nghttp2.
 */

/* Per-stream data provider state for streaming responses */
typedef struct {
    SV *callback;           /* Perl callback to produce data */
    SV *user_data;          /* User data for callback */
    int32_t stream_id;      /* Stream ID */
    int eof;                /* End of data flag */
    int deferred;           /* Currently deferred */
} nghttp2_perl_data_provider;

/* Session wrapper structure */
typedef struct {
    nghttp2_session *session;
    SV *user_data;
    SV *cb_on_begin_headers;
    SV *cb_on_header;
    SV *cb_on_frame_recv;
    SV *cb_on_data_chunk_recv;
    SV *cb_on_stream_close;
    SV *cb_send;
    SV *cb_data_source_read;
    /* Output buffer for mem_send */
    char *send_buf;
    size_t send_buf_len;
    size_t send_buf_cap;
    /* Data providers for active streams (simple linear array) */
    nghttp2_perl_data_provider **data_providers;
    int data_providers_count;
    int data_providers_cap;
} nghttp2_perl_session;

/* Forward declarations */
static ssize_t perl_send_callback(nghttp2_session *session,
                                  const uint8_t *data, size_t length,
                                  int flags, void *user_data);
static int perl_on_begin_headers_callback(nghttp2_session *session,
                                          const nghttp2_frame *frame,
                                          void *user_data);
static int perl_on_header_callback(nghttp2_session *session,
                                   const nghttp2_frame *frame,
                                   const uint8_t *name, size_t namelen,
                                   const uint8_t *value, size_t valuelen,
                                   uint8_t flags, void *user_data);
static int perl_on_frame_recv_callback(nghttp2_session *session,
                                       const nghttp2_frame *frame,
                                       void *user_data);
static int perl_on_data_chunk_recv_callback(nghttp2_session *session,
                                            uint8_t flags, int32_t stream_id,
                                            const uint8_t *data, size_t len,
                                            void *user_data);
static int perl_on_stream_close_callback(nghttp2_session *session,
                                         int32_t stream_id,
                                         uint32_t error_code,
                                         void *user_data);

/* Data provider helper functions */
static nghttp2_perl_data_provider *find_data_provider(nghttp2_perl_session *ps, int32_t stream_id) {
    int i;
    for (i = 0; i < ps->data_providers_count; i++) {
        if (ps->data_providers[i] && ps->data_providers[i]->stream_id == stream_id) {
            return ps->data_providers[i];
        }

nghttp2.c  view on Meta::CPAN

{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "self, stream_id, data");
    {
	SV *	self = ST(0)
;
	int	stream_id = (int)SvIV(ST(1))
;
	SV *	data = ST(2)
;
#line 1066 "nghttp2.xs"
        nghttp2_perl_session *ps;
        int rv;
#line 1721 "nghttp2.c"
	int	RETVAL;
	dXSTARG;
#line 1069 "nghttp2.xs"
        ps = (nghttp2_perl_session *)SvIV(SvRV(self));
        /* Note: caller must ensure data SV survives */
        rv = nghttp2_session_set_stream_user_data(ps->session, stream_id,
                                                   SvOK(data) ? newSVsv(data) : NULL);
        RETVAL = rv;
#line 1730 "nghttp2.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Net__HTTP2__nghttp2__Session_terminate_session); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Net__HTTP2__nghttp2__Session_terminate_session)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, error_code");
    {
	SV *	self = ST(0)
;
	int	error_code = (int)SvIV(ST(1))
;
#line 1083 "nghttp2.xs"
        nghttp2_perl_session *ps;
        int rv;
#line 1752 "nghttp2.c"
	int	RETVAL;
	dXSTARG;
#line 1086 "nghttp2.xs"
        ps = (nghttp2_perl_session *)SvIV(SvRV(self));
        rv = nghttp2_session_terminate_session(ps->session, error_code);
        RETVAL = rv;
#line 1759 "nghttp2.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Net__HTTP2__nghttp2__Session__submit_response_streaming); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Net__HTTP2__nghttp2__Session__submit_response_streaming)
{
    dVAR; dXSARGS;
    if (items != 5)
       croak_xs_usage(cv,  "self, stream_id, headers_av, data_callback, cb_user_data");
    {
	SV *	self = ST(0)
;
	int	stream_id = (int)SvIV(ST(1))
;
	AV *	headers_av;
	SV *	data_callback = ST(3)
;
	SV *	cb_user_data = ST(4)
;
#line 1103 "nghttp2.xs"
        nghttp2_perl_session *ps;
        nghttp2_nv *nva;
        size_t nvlen;
        nghttp2_data_provider data_prd;
        nghttp2_perl_data_provider *dp;
        int rv;
        I32 i;
#line 1791 "nghttp2.c"
	int	RETVAL;
	dXSTARG;

	STMT_START {
		SV* const xsub_tmp_sv = ST(2);
		SvGETMAGIC(xsub_tmp_sv);
		if (SvROK(xsub_tmp_sv) && SvTYPE(SvRV(xsub_tmp_sv)) == SVt_PVAV){
		    headers_av = (AV*)SvRV(xsub_tmp_sv);
		}
		else{
		    Perl_croak_nocontext("%s: %s is not an ARRAY reference",
				"Net::HTTP2::nghttp2::Session::_submit_response_streaming",
				"headers_av");
		}
	} STMT_END
;
#line 1111 "nghttp2.xs"
        ps = (nghttp2_perl_session *)SvIV(SvRV(self));

        /* Build name-value array from Perl array of arrayrefs */
        nvlen = av_len(headers_av) + 1;
        Newxz(nva, nvlen, nghttp2_nv);

        for (i = 0; i < (I32)nvlen; i++) {
            SV **pair = av_fetch(headers_av, i, 0);
            if (pair && SvROK(*pair) && SvTYPE(SvRV(*pair)) == SVt_PVAV) {
                AV *pair_av = (AV *)SvRV(*pair);
                SV **name_sv = av_fetch(pair_av, 0, 0);
                SV **value_sv = av_fetch(pair_av, 1, 0);

                if (name_sv && value_sv) {
                    STRLEN name_len, value_len;
                    nva[i].name = (uint8_t *)SvPVbyte(*name_sv, name_len);
                    nva[i].namelen = name_len;
                    nva[i].value = (uint8_t *)SvPVbyte(*value_sv, value_len);
                    nva[i].valuelen = value_len;
                    nva[i].flags = NGHTTP2_NV_FLAG_NONE;
                }
            }
        }

        /* Create data provider state */
        Newxz(dp, 1, nghttp2_perl_data_provider);
        dp->stream_id = stream_id;
        dp->callback = newSVsv(data_callback);
        if (SvOK(cb_user_data)) {
            dp->user_data = newSVsv(cb_user_data);
        }
        dp->eof = 0;
        dp->deferred = 0;

        /* Track the data provider */
        add_data_provider(ps, dp);

        /* Set up nghttp2 data provider */
        data_prd.source.ptr = dp;
        data_prd.read_callback = perl_data_source_read_callback;

        rv = nghttp2_submit_response(ps->session, stream_id, nva, nvlen, &data_prd);

        Safefree(nva);

        if (rv != 0) {
            remove_data_provider(ps, stream_id);
            croak("nghttp2_submit_response failed: %s", nghttp2_strerror(rv));
        }
        RETVAL = rv;
#line 1859 "nghttp2.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);

nghttp2.c  view on Meta::CPAN

    {
	SV *	self = ST(0)
;
	AV *	headers_av;
	SV *	body_sv = ST(2)
;
#line 1326 "nghttp2.xs"
        nghttp2_perl_session *ps;
        nghttp2_nv *nva;
        size_t nvlen;
        nghttp2_data_provider data_prd;
        nghttp2_data_provider *data_prd_ptr = NULL;
        nghttp2_perl_data_provider *dp = NULL;
        int32_t stream_id;
        I32 i;
        STRLEN body_len = 0;
#line 2107 "nghttp2.c"
	int	RETVAL;
	dXSTARG;

	STMT_START {
		SV* const xsub_tmp_sv = ST(1);
		SvGETMAGIC(xsub_tmp_sv);
		if (SvROK(xsub_tmp_sv) && SvTYPE(SvRV(xsub_tmp_sv)) == SVt_PVAV){
		    headers_av = (AV*)SvRV(xsub_tmp_sv);
		}
		else{
		    Perl_croak_nocontext("%s: %s is not an ARRAY reference",
				"Net::HTTP2::nghttp2::Session::_submit_request_xs",
				"headers_av");
		}
	} STMT_END
;
#line 1336 "nghttp2.xs"
        ps = (nghttp2_perl_session *)SvIV(SvRV(self));

        /* Build name-value array from Perl array of arrayrefs */
        nvlen = av_len(headers_av) + 1;
        Newxz(nva, nvlen, nghttp2_nv);

        for (i = 0; i < (I32)nvlen; i++) {
            SV **pair = av_fetch(headers_av, i, 0);
            if (pair && SvROK(*pair) && SvTYPE(SvRV(*pair)) == SVt_PVAV) {
                AV *pair_av = (AV *)SvRV(*pair);
                SV **name_sv = av_fetch(pair_av, 0, 0);
                SV **value_sv = av_fetch(pair_av, 1, 0);

                if (name_sv && value_sv) {
                    STRLEN name_len, value_len;
                    nva[i].name = (uint8_t *)SvPVbyte(*name_sv, name_len);
                    nva[i].namelen = name_len;
                    nva[i].value = (uint8_t *)SvPVbyte(*value_sv, value_len);
                    nva[i].valuelen = value_len;
                    nva[i].flags = NGHTTP2_NV_FLAG_NONE;
                }
            }
        }

        /* Check if we have a body to send */
        if (SvOK(body_sv) && SvROK(body_sv) && SvTYPE(SvRV(body_sv)) == SVt_PVCV) {
            /* CODE ref body: streaming callback data provider */
            Newxz(dp, 1, nghttp2_perl_data_provider);
            dp->stream_id = 0;  /* Will be set after submit */
            dp->eof = 0;
            dp->deferred = 0;
            dp->callback = newSVsv(body_sv);

            data_prd.source.ptr = dp;
            data_prd.read_callback = perl_data_source_read_callback;
            data_prd_ptr = &data_prd;
        }
        else if (SvOK(body_sv) && SvPOK(body_sv)) {
            const char *body_ptr = SvPVbyte(body_sv, body_len);
            if (body_len > 0) {
                /* Static string body: one-shot data provider */
                Newxz(dp, 1, nghttp2_perl_data_provider);
                dp->stream_id = 0;  /* Will be set after submit */
                dp->eof = 1;       /* Static bodies always want EOF after sending */
                dp->deferred = 0;
                dp->user_data = newSVsv(body_sv);
                dp->callback = NULL;  /* Use user_data as body */

                data_prd.source.ptr = dp;
                data_prd.read_callback = perl_data_source_read_callback;
                data_prd_ptr = &data_prd;
            }
        }

        stream_id = nghttp2_submit_request(ps->session, NULL, nva, nvlen, data_prd_ptr, NULL);

        Safefree(nva);

        if (stream_id < 0) {
            if (dp) {
                if (dp->callback) SvREFCNT_dec(dp->callback);
                if (dp->user_data) SvREFCNT_dec(dp->user_data);
                Safefree(dp);
            }
            croak("nghttp2_submit_request failed: %s", nghttp2_strerror(stream_id));
        }

        /* Track data provider if we have one */
        if (dp) {
            dp->stream_id = stream_id;
            add_data_provider(ps, dp);
        }

        RETVAL = stream_id;
#line 2199 "nghttp2.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Net__HTTP2__nghttp2__Session_submit_rst_stream); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Net__HTTP2__nghttp2__Session_submit_rst_stream)
{
    dVAR; dXSARGS;
    if (items != 3)

nghttp2.c  view on Meta::CPAN

#if PERL_VERSION_LE(5, 21, 5)
    dVAR; dXSARGS;
#else
    dVAR; dXSBOOTARGSXSAPIVERCHK;
#endif
#if PERL_VERSION_LE(5, 8, 999) /* PERL_VERSION_LT is 5.33+ */
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(file);

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#if PERL_VERSION_LE(5, 21, 5)
    XS_VERSION_BOOTCHECK;
#  ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#  endif
#endif

        newXS_deffile("Net::HTTP2::nghttp2::_check_nghttp2_available", XS_Net__HTTP2__nghttp2__check_nghttp2_available);
        newXS_deffile("Net::HTTP2::nghttp2::version_string", XS_Net__HTTP2__nghttp2_version_string);
        newXS_deffile("Net::HTTP2::nghttp2::version_num", XS_Net__HTTP2__nghttp2_version_num);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_ERR_WOULDBLOCK", XS_Net__HTTP2__nghttp2_NGHTTP2_ERR_WOULDBLOCK);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_ERR_CALLBACK_FAILURE", XS_Net__HTTP2__nghttp2_NGHTTP2_ERR_CALLBACK_FAILURE);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_ERR_DEFERRED", XS_Net__HTTP2__nghttp2_NGHTTP2_ERR_DEFERRED);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE", XS_Net__HTTP2__nghttp2_NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_FLAG_NONE", XS_Net__HTTP2__nghttp2_NGHTTP2_FLAG_NONE);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_FLAG_END_STREAM", XS_Net__HTTP2__nghttp2_NGHTTP2_FLAG_END_STREAM);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_FLAG_END_HEADERS", XS_Net__HTTP2__nghttp2_NGHTTP2_FLAG_END_HEADERS);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_FLAG_ACK", XS_Net__HTTP2__nghttp2_NGHTTP2_FLAG_ACK);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS", XS_Net__HTTP2__nghttp2_NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE", XS_Net__HTTP2__nghttp2_NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_SETTINGS_MAX_FRAME_SIZE", XS_Net__HTTP2__nghttp2_NGHTTP2_SETTINGS_MAX_FRAME_SIZE);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_SETTINGS_ENABLE_PUSH", XS_Net__HTTP2__nghttp2_NGHTTP2_SETTINGS_ENABLE_PUSH);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL", XS_Net__HTTP2__nghttp2_NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_DATA_FLAG_NONE", XS_Net__HTTP2__nghttp2_NGHTTP2_DATA_FLAG_NONE);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_DATA_FLAG_EOF", XS_Net__HTTP2__nghttp2_NGHTTP2_DATA_FLAG_EOF);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_DATA_FLAG_NO_END_STREAM", XS_Net__HTTP2__nghttp2_NGHTTP2_DATA_FLAG_NO_END_STREAM);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_DATA_FLAG_NO_COPY", XS_Net__HTTP2__nghttp2_NGHTTP2_DATA_FLAG_NO_COPY);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_DATA", XS_Net__HTTP2__nghttp2_NGHTTP2_DATA);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_HEADERS", XS_Net__HTTP2__nghttp2_NGHTTP2_HEADERS);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_SETTINGS", XS_Net__HTTP2__nghttp2_NGHTTP2_SETTINGS);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_PUSH_PROMISE", XS_Net__HTTP2__nghttp2_NGHTTP2_PUSH_PROMISE);
        newXS_deffile("Net::HTTP2::nghttp2::NGHTTP2_GOAWAY", XS_Net__HTTP2__nghttp2_NGHTTP2_GOAWAY);
        newXS_deffile("Net::HTTP2::nghttp2::Session::_new_server_xs", XS_Net__HTTP2__nghttp2__Session__new_server_xs);
        newXS_deffile("Net::HTTP2::nghttp2::Session::DESTROY", XS_Net__HTTP2__nghttp2__Session_DESTROY);
        newXS_deffile("Net::HTTP2::nghttp2::Session::mem_recv", XS_Net__HTTP2__nghttp2__Session_mem_recv);
        newXS_deffile("Net::HTTP2::nghttp2::Session::mem_send", XS_Net__HTTP2__nghttp2__Session_mem_send);
        newXS_deffile("Net::HTTP2::nghttp2::Session::want_read", XS_Net__HTTP2__nghttp2__Session_want_read);
        newXS_deffile("Net::HTTP2::nghttp2::Session::want_write", XS_Net__HTTP2__nghttp2__Session_want_write);
        newXS_deffile("Net::HTTP2::nghttp2::Session::submit_settings", XS_Net__HTTP2__nghttp2__Session_submit_settings);
        newXS_deffile("Net::HTTP2::nghttp2::Session::_submit_response_with_body", XS_Net__HTTP2__nghttp2__Session__submit_response_with_body);
        newXS_deffile("Net::HTTP2::nghttp2::Session::_submit_response_no_body", XS_Net__HTTP2__nghttp2__Session__submit_response_no_body);
        newXS_deffile("Net::HTTP2::nghttp2::Session::resume_data", XS_Net__HTTP2__nghttp2__Session_resume_data);
        newXS_deffile("Net::HTTP2::nghttp2::Session::get_stream_user_data", XS_Net__HTTP2__nghttp2__Session_get_stream_user_data);
        newXS_deffile("Net::HTTP2::nghttp2::Session::set_stream_user_data", XS_Net__HTTP2__nghttp2__Session_set_stream_user_data);
        newXS_deffile("Net::HTTP2::nghttp2::Session::terminate_session", XS_Net__HTTP2__nghttp2__Session_terminate_session);
        newXS_deffile("Net::HTTP2::nghttp2::Session::_submit_response_streaming", XS_Net__HTTP2__nghttp2__Session__submit_response_streaming);
        newXS_deffile("Net::HTTP2::nghttp2::Session::submit_data", XS_Net__HTTP2__nghttp2__Session_submit_data);
        newXS_deffile("Net::HTTP2::nghttp2::Session::is_stream_deferred", XS_Net__HTTP2__nghttp2__Session_is_stream_deferred);
        newXS_deffile("Net::HTTP2::nghttp2::Session::_clear_deferred", XS_Net__HTTP2__nghttp2__Session__clear_deferred);
        newXS_deffile("Net::HTTP2::nghttp2::Session::_new_client_xs", XS_Net__HTTP2__nghttp2__Session__new_client_xs);
        newXS_deffile("Net::HTTP2::nghttp2::Session::_submit_request_xs", XS_Net__HTTP2__nghttp2__Session__submit_request_xs);
        newXS_deffile("Net::HTTP2::nghttp2::Session::submit_rst_stream", XS_Net__HTTP2__nghttp2__Session_submit_rst_stream);
        newXS_deffile("Net::HTTP2::nghttp2::Session::submit_ping", XS_Net__HTTP2__nghttp2__Session_submit_ping);
        newXS_deffile("Net::HTTP2::nghttp2::Session::submit_window_update", XS_Net__HTTP2__nghttp2__Session_submit_window_update);
#if PERL_VERSION_LE(5, 21, 5)
#  if PERL_VERSION_GE(5, 9, 0)
    if (PL_unitcheckav)
        call_list(PL_scopestack_ix, PL_unitcheckav);
#  endif
    XSRETURN_YES;
#else
    Perl_xs_boot_epilog(aTHX_ ax);
#endif
}

#ifdef __cplusplus
}
#endif



( run in 0.575 second using v1.01-cache-2.11-cpan-140bd7fdf52 )