/* Licensed to the Apache Software Foundation (ASF) under one or more *contributorlicenseagreements.SeetheNOTICEfiledistributedwith *thisworkforadditionalinformationregardingcopyrightownership. *TheASFlicensesthisfiletoYouundertheApacheLicense,Version2.0 *(the"License");youmaynotusethisfileexceptincompliancewith *theLicense.YoumayobtainacopyoftheLicenseat * *http://www.apache.org/licenses/LICENSE-2.0 * *Unlessrequiredbyapplicablelaworagreedtoinwriting,software *distributedundertheLicenseisdistributedonan"ASIS"BASIS, *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. *SeetheLicenseforthespecificlanguagegoverningpermissionsand *limitationsundertheLicense.
*/
/* Calculated like this: assuming MTU 1500 bytes *1500-40(IP)-20(TCP)-40(TCPoptions) *-TLSoverhead(60-100)
* ~= 1300 bytes */ #define WRITE_SIZE_INITIAL 1300
/* The maximum we'd like to write in one chunk is *themaxsizeofaTLSrecord.Whenpushing *manyframesdowntheh2connection,thismight *aligndifferentlybecauseofheadersandother *framesorsimplyasnotsufficientdatais *inaresponsebody. *Howeverkeepingframesatorbelowthislimit *shouldmakeoptimizationsatthelayerthatwrites *toTLSeasier.
*/ #define WRITE_SIZE_MAX (TLS_DATA_MAX)
#define BUF_REMAIN ((apr_size_t)(bmax-off))
staticvoid h2_c1_io_bb_log(conn_rec *c, int stream_id, int level, constchar *tag, apr_bucket_brigade *bb)
{ char buffer[16 * 1024]; constchar *line = "(null)"; int bmax = sizeof(buffer)/sizeof(buffer[0]); int off = 0;
apr_bucket *b;
(void)stream_id; if (bb) {
memset(buffer, 0, bmax--); for (b = APR_BRIGADE_FIRST(bb);
bmax && (b != APR_BRIGADE_SENTINEL(bb));
b = APR_BUCKET_NEXT(b)) {
if (io->is_passing) { /* recursive call, may be triggered by an H2EOS bucket
* being destroyed and triggering sending more data? */
AP_DEBUG_ASSERT(0);
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10456) "h2_c1_io(%ld): recursive call of h2_c1_io_pass. " "Denied to prevent output corruption. This " "points to a bug in the HTTP/2 implementation.",
c->id); return APR_EGENERAL;
}
io->is_passing = 1;
append_scratch(io); if (flush) { if (!APR_BUCKET_IS_FLUSH(APR_BRIGADE_LAST(io->output))) {
apr_bucket *b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(io->output, b);
}
} if (APR_BRIGADE_EMPTY(io->output)) {
rv = APR_SUCCESS; goto cleanup;
}
/* H2_IN filter handles all incoming data against the session.
* We just pull at the filter chain to make it happen */
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1,
H2_SSSN_MSG(session, "session_read start"));
rv = read_and_feed(session);
if (APR_SUCCESS == rv) {
h2_session_dispatch_event(session, H2_SESSION_EV_INPUT_PENDING, 0, NULL);
} elseif (APR_STATUS_IS_EAGAIN(rv)) { /* Signal that we have exhausted the input momentarily.
* This might switch to polling the socket */
h2_session_dispatch_event(session, H2_SESSION_EV_INPUT_EXHAUSTED, 0, NULL);
} elseif (APR_SUCCESS != rv) { if (APR_STATUS_IS_ETIMEDOUT(rv)
|| APR_STATUS_IS_ECONNABORTED(rv)
|| APR_STATUS_IS_ECONNRESET(rv)
|| APR_STATUS_IS_EOF(rv)
|| APR_STATUS_IS_EBADF(rv)) { /* common status for a client that has left */
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, rv, session->c1,
H2_SSSN_MSG(session, "input gone"));
} else { /* uncommon status, log on INFO so that we see this */
ap_log_cerror( APLOG_MARK, APLOG_DEBUG, rv, session->c1,
H2_SSSN_LOG(APLOGNO(02950), session, "error reading, terminating"));
}
h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, 0, NULL);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.