Author: rhuijben
Date: Tue Nov 17 09:18:11 2015
New Revision: 1714736
URL: http://svn.apache.org/viewvc?rev=1714736&view=rev
Log:
Following up on r1714735, add a basic protocol handler for fcgi on the server
side.
* incoming.c
(serf_incoming_set_framing_type): Initialize fcgi if requested.
* protocols/fcgi_protocol.c
New file.
* protocols/fcgi_protocol.h
New file.
* protocols/fcgi_stream.c
New file.
* serf.h
(serf_connection_framing_type_t): Extend enum.
* serf_private.h
(serf__fcgi_protocol_init,
serf__fcgi_protocol_init_server): New function.
* test/serf_httpd.c
(client_accept): Allow listening for specific protocols.
E.g. --listen 127.0.0.1:99 --listen fcgi,127.0.0.1:4000 /my/web/root
Added:
serf/trunk/protocols/fcgi_protocol.c (with props)
serf/trunk/protocols/fcgi_protocol.h (with props)
serf/trunk/protocols/fcgi_stream.c (with props)
Modified:
serf/trunk/incoming.c
serf/trunk/serf.h
serf/trunk/serf_private.h
serf/trunk/test/serf_httpd.c
Modified: serf/trunk/incoming.c
URL:
http://svn.apache.org/viewvc/serf/trunk/incoming.c?rev=1714736&r1=1714735&r2=1714736&view=diff
==============================================================================
--- serf/trunk/incoming.c (original)
+++ serf/trunk/incoming.c Tue Nov 17 09:18:11 2015
@@ -580,6 +580,8 @@ void serf_incoming_set_framing_type(
case SERF_CONNECTION_FRAMING_TYPE_HTTP2:
serf__http2_protocol_init_server(client);
break;
+ case SERF_CONNECTION_FRAMING_TYPE_FCGI:
+ serf__fcgi_protocol_init_server(client);
default:
break;
}
Added: serf/trunk/protocols/fcgi_protocol.c
URL:
http://svn.apache.org/viewvc/serf/trunk/protocols/fcgi_protocol.c?rev=1714736&view=auto
==============================================================================
--- serf/trunk/protocols/fcgi_protocol.c (added)
+++ serf/trunk/protocols/fcgi_protocol.c Tue Nov 17 09:18:11 2015
@@ -0,0 +1,400 @@
+/* ====================================================================
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+* ====================================================================
+*/
+
+#include <apr_pools.h>
+#include <apr_poll.h>
+#include <apr_version.h>
+#include <apr_portable.h>
+#include <apr_strings.h>
+
+#include "serf.h"
+#include "serf_bucket_util.h"
+
+#include "serf_private.h"
+#include "protocols/fcgi_buckets.h"
+#include "protocols/fcgi_protocol.h"
+
+typedef struct serf_fcgi_protocol_t
+{
+ serf_context_t *ctx;
+ serf_connection_t *conn;
+ serf_incoming_t *client;
+
+ apr_pool_t *pool;
+ serf_bucket_alloc_t *allocator;
+ bool *dirty_pollset;
+ serf_config_t *config;
+
+ apr_int16_t *req_events;
+
+ serf_bucket_t *stream;
+ serf_bucket_t *ostream;
+
+ serf_fcgi_processor_t processor;
+ void *processor_baton;
+
+ serf_bucket_t *read_frame;
+ bool in_frame;
+
+} serf_fcgi_protocol_t;
+
+static apr_status_t fcgi_cleanup(void *baton)
+{
+ serf_fcgi_protocol_t *fcgi = baton;
+
+ fcgi = fcgi;
+
+ return APR_SUCCESS;
+}
+
+/* Implements the serf_bucket_end_of_frame_t callback */
+static apr_status_t
+fcgi_end_of_frame(void *baton,
+ serf_bucket_t *frame)
+{
+ serf_fcgi_protocol_t *fcgi = baton;
+
+ SERF_FCGI_assert(fcgi->read_frame == frame);
+ fcgi->read_frame = NULL;
+ fcgi->in_frame = FALSE;
+ fcgi->processor = NULL;
+ fcgi->processor_baton = NULL;
+
+ return APR_SUCCESS;
+}
+
+/* Implements serf_fcgi_processor_t */
+static apr_status_t
+fcgi_bucket_processor(void *baton,
+ serf_fcgi_protocol_t *h2,
+ serf_bucket_t *frame_bucket)
+{
+ struct iovec vecs[IOV_MAX];
+ int vecs_used;
+ serf_bucket_t *payload = baton;
+ apr_status_t status;
+
+ status = serf_bucket_read_iovec(payload, SERF_READ_ALL_AVAIL, IOV_MAX,
+ vecs, &vecs_used);
+
+ if (APR_STATUS_IS_EOF(status))
+ {
+ SERF_FCGI_assert(!h2->in_frame && !h2->read_frame);
+ serf_bucket_destroy(payload);
+ }
+
+ return status;
+}
+
+
+
+static apr_status_t fcgi_process(serf_fcgi_protocol_t *fcgi)
+{
+ while (true)
+ {
+ apr_status_t status;
+ serf_bucket_t *body;
+
+ if (fcgi->processor)
+ {
+ status = fcgi->processor(fcgi->processor_baton, fcgi,
+ fcgi->read_frame);
+
+ if (SERF_BUCKET_READ_ERROR(status))
+ return status;
+ else if (APR_STATUS_IS_EOF(status))
+ {
+ /* ### frame ended */
+ SERF_FCGI_assert(fcgi->read_frame == NULL);
+ fcgi->processor = NULL;
+ fcgi->processor_baton = NULL;
+ }
+ else if (fcgi->in_frame)
+ {
+ if (status)
+ return status;
+ else
+ continue;
+ }
+ }
+ else
+ {
+ SERF_FCGI_assert(!fcgi->in_frame);
+ }
+
+ body = fcgi->read_frame;
+
+ if (!body)
+ {
+ SERF_FCGI_assert(!fcgi->in_frame);
+
+ body = serf__bucket_fcgi_unframe_create(fcgi->stream,
+ fcgi->allocator);
+
+ serf__bucket_fcgi_unframe_set_eof(body,
+ fcgi_end_of_frame, fcgi);
+
+ serf_bucket_set_config(body, fcgi->config);
+ fcgi->read_frame = body;
+ }
+
+ if (!fcgi->in_frame)
+ {
+ apr_uint16_t sid;
+ apr_uint16_t frametype;
+ apr_size_t remaining;
+ serf_fcgi_processor_t process_handler = NULL;
+ void *process_baton = NULL;
+ serf_bucket_t *process_bucket = NULL;
+ serf_fcgi_stream_t *stream;
+ apr_uint32_t reset_reason;
+
+ status = serf__bucket_fcgi_unframe_read_info(body, &sid,
+ &frametype);
+
+ if (APR_STATUS_IS_EOF(status))
+ {
+ /* Entire frame is already read (just header) */
+ SERF_FCGI_assert(fcgi->read_frame == NULL);
+ SERF_FCGI_assert(!fcgi->in_frame);
+ }
+ else if (status)
+ {
+ SERF_FCGI_assert(fcgi->read_frame != NULL);
+ SERF_FCGI_assert(!fcgi->in_frame);
+ return status;
+ }
+ else
+ {
+ fcgi->in_frame = TRUE;
+ SERF_FCGI_assert(fcgi->read_frame != NULL);
+ }
+
+ serf__log(LOGLVL_INFO, SERF_LOGFCGI, fcgi->config,
+ "Reading 0x%x frame, stream=0x%x\n",
+ frametype, sid);
+
+ /* If status is EOF then the frame doesn't have/declare a body */
+ switch (frametype)
+ {
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_BEGIN_REQUEST):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_ABORT_REQUEST):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_END_REQUEST):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_PARAMS):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_STDIN):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_STDOUT):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_STDERR):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_DATA):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_GET_VALUES):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_GET_VALUES_RESULT):
+ process_bucket = body;
+ break;
+ case FCGI_FRAMETYPE(FCGI_V1, FCGI_UNKNOWN_TYPE):
+ process_bucket = body;
+ break;
+ default:
+ process_bucket = body;
+ };
+
+ if (body)
+ serf_bucket_set_config(body, fcgi->config);
+
+ SERF_FCGI_assert(fcgi->processor == NULL);
+
+ if (process_handler)
+ {
+ fcgi->processor = process_handler;
+ fcgi->processor_baton = process_baton;
+ }
+ else
+ {
+ SERF_FCGI_assert(process_bucket != NULL);
+ fcgi->processor = fcgi_bucket_processor;
+ fcgi->processor_baton = process_bucket;
+ }
+ }
+ } /* while(TRUE) */
+}
+
+static apr_status_t fcgi_read(serf_fcgi_protocol_t *fcgi)
+{
+ apr_status_t status = fcgi_process(fcgi);
+
+ if (!status || SERF_BUCKET_READ_ERROR(status))
+ return status;
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t fcgi_write(serf_fcgi_protocol_t *fcgi)
+{
+ return APR_ENOTIMPL;
+}
+
+static apr_status_t fcgi_teardown(serf_fcgi_protocol_t *fcgi)
+{
+ return APR_ENOTIMPL;
+}
+
+
+/* --------------- connection support --------------- */
+static apr_status_t fcgi_outgoing_read(serf_connection_t *conn)
+{
+ serf_fcgi_protocol_t *fcgi = conn->protocol_baton;
+
+ if (!fcgi->stream)
+ fcgi->stream = conn->stream;
+
+ return fcgi_read(fcgi);
+}
+
+static apr_status_t fcgi_outgoing_write(serf_connection_t *conn)
+{
+ serf_fcgi_protocol_t *fcgi = conn->protocol_baton;
+
+ return fcgi_read(fcgi);
+}
+
+static apr_status_t fcgi_outgoing_hangup(serf_connection_t *conn)
+{
+ serf_fcgi_protocol_t *fcgi = conn->protocol_baton;
+
+ return fcgi_read(fcgi);
+}
+
+static apr_status_t fcgi_outgoing_teardown(serf_connection_t *conn)
+{
+ serf_fcgi_protocol_t *fcgi = conn->protocol_baton;
+
+ return fcgi_read(fcgi);
+}
+
+void serf__fcgi_protocol_init(serf_connection_t *conn)
+{
+ serf_fcgi_protocol_t *fcgi;
+ apr_pool_t *protocol_pool;
+
+ apr_pool_create(&protocol_pool, conn->pool);
+
+ fcgi = apr_pcalloc(protocol_pool, sizeof(*fcgi));
+ fcgi->pool = protocol_pool;
+ fcgi->conn = conn;
+ fcgi->ctx = conn->ctx;
+ fcgi->dirty_pollset = &conn->dirty_conn;
+ fcgi->req_events = &conn->reqevents;
+ fcgi->stream = conn->stream;
+ fcgi->ostream = conn->ostream_tail;
+ fcgi->allocator = conn->allocator;
+ fcgi->config = conn->config;
+
+ apr_pool_cleanup_register(protocol_pool, fcgi, fcgi_cleanup,
+ apr_pool_cleanup_null);
+
+ conn->perform_read = fcgi_outgoing_read;
+ conn->perform_write = fcgi_outgoing_write;
+ conn->perform_hangup = fcgi_outgoing_hangup;
+ conn->perform_teardown = fcgi_outgoing_teardown;
+ conn->protocol_baton = fcgi;
+
+ /* Disable HTTP/1.1 guessing that affects writability */
+ conn->probable_keepalive_limit = 0;
+ conn->max_outstanding_requests = 0;
+}
+
+/* --------------- connection support --------------- */
+static apr_status_t fcgi_server_read(serf_incoming_t *client)
+{
+ serf_fcgi_protocol_t *fcgi = client->protocol_baton;
+
+ if (! fcgi->stream) {
+ fcgi->stream = client->stream;
+ fcgi->ostream = client->ostream_tail;
+ }
+
+ return fcgi_read(fcgi);
+}
+
+static apr_status_t fcgi_server_write(serf_incoming_t *client)
+{
+ serf_fcgi_protocol_t *fcgi = client->protocol_baton;
+
+ return fcgi_read(fcgi);
+}
+
+static apr_status_t fcgi_server_hangup(serf_incoming_t *client)
+{
+ serf_fcgi_protocol_t *fcgi = client->protocol_baton;
+
+ return fcgi_read(fcgi);
+}
+
+static apr_status_t fcgi_server_teardown(serf_incoming_t *client)
+{
+ serf_fcgi_protocol_t *fcgi = client->protocol_baton;
+
+ return fcgi_read(fcgi);
+}
+
+void serf__fcgi_protocol_init_server(serf_incoming_t *client)
+{
+ serf_fcgi_protocol_t *fcgi;
+ apr_pool_t *protocol_pool;
+
+ apr_pool_create(&protocol_pool, client->pool);
+
+ fcgi = apr_pcalloc(protocol_pool, sizeof(*fcgi));
+ fcgi->pool = protocol_pool;
+ fcgi->client = client;
+ fcgi->ctx = client->ctx;
+ fcgi->dirty_pollset = &client->dirty_conn;
+ fcgi->req_events = &client->reqevents;
+ fcgi->stream = client->stream;
+ fcgi->ostream = client->ostream_tail;
+ fcgi->allocator = client->allocator;
+ fcgi->config = client->config;
+
+ apr_pool_cleanup_register(protocol_pool, fcgi, fcgi_cleanup,
+ apr_pool_cleanup_null);
+
+ client->perform_read = fcgi_server_read;
+ client->perform_write = fcgi_server_write;
+ client->perform_hangup = fcgi_server_hangup;
+ client->perform_teardown = fcgi_server_teardown;
+ client->protocol_baton = fcgi;
+}
+
Propchange: serf/trunk/protocols/fcgi_protocol.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: serf/trunk/protocols/fcgi_protocol.h
URL:
http://svn.apache.org/viewvc/serf/trunk/protocols/fcgi_protocol.h?rev=1714736&view=auto
==============================================================================
--- serf/trunk/protocols/fcgi_protocol.h (added)
+++ serf/trunk/protocols/fcgi_protocol.h Tue Nov 17 09:18:11 2015
@@ -0,0 +1,88 @@
+/* ====================================================================
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+* ====================================================================
+*/
+
+#ifndef SERF_PROTOCOL_FCGI_PROTOCOL_H
+#define SERF_PROTOCOL_FCGI_PROTOCOL_H
+
+#include "serf_bucket_types.h"
+
+#ifdef _DEBUG
+#include <assert.h>
+#define SERF_FCGI_assert(x) assert(x)
+#else
+#define SERF_FCGI_assert(x) ((void)0)
+#endif
+
+#define SERF_LOGFCGI \
+ SERF_LOGCOMP_PROTOCOL, (__FILE__ ":" APR_STRINGIFY(__LINE__))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct serf_fcgi_protocol_t serf_fcgi_protocol_t;
+typedef struct serf_fcgi_stream_data_t serf_fcgi_stream_data_t;
+
+#define FCGI_FRAMETYPE(version, type) \
+ ( ( (apr_uint16_t)(unsigned char)(version) << 8) \
+ | ( (apr_uint16_t)(unsigned char)(type)))
+
+#define FCGI_V1 0x1
+
+#define FCGI_BEGIN_REQUEST 1
+#define FCGI_ABORT_REQUEST 2
+#define FCGI_END_REQUEST 3
+#define FCGI_PARAMS 4
+#define FCGI_STDIN 5
+#define FCGI_STDOUT 6
+#define FCGI_STDERR 7
+#define FCGI_DATA 8
+#define FCGI_GET_VALUES 9
+#define FCGI_GET_VALUES_RESULT 10
+#define FCGI_UNKNOWN_TYPE 11
+#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)
+
+
+typedef struct serf_fcgi_stream_t
+{
+ struct serf_fcgi_protocol_t *h2;
+ serf_bucket_alloc_t *alloc;
+
+ /* Opaque implementation details */
+ serf_fcgi_stream_data_t *data;
+
+ /* Linked list of currently existing streams */
+ struct serf_fcgi_stream_t *next;
+ struct serf_fcgi_stream_t *prev;
+} serf_fcgi_stream_t;
+
+typedef apr_status_t(*serf_fcgi_processor_t)(void *baton,
+ serf_fcgi_protocol_t *fcgi,
+ serf_bucket_t *body);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !SERF_PROTOCOL_FCGI_PROTOCOL_H */
+
+
Propchange: serf/trunk/protocols/fcgi_protocol.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: serf/trunk/protocols/fcgi_stream.c
URL:
http://svn.apache.org/viewvc/serf/trunk/protocols/fcgi_stream.c?rev=1714736&view=auto
==============================================================================
--- serf/trunk/protocols/fcgi_stream.c (added)
+++ serf/trunk/protocols/fcgi_stream.c Tue Nov 17 09:18:11 2015
@@ -0,0 +1,57 @@
+/* ====================================================================
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+* ====================================================================
+*/
+
+#include <stdlib.h>
+
+#include <apr_pools.h>
+#include <apr_strings.h>
+
+#include "serf.h"
+#include "serf_bucket_util.h"
+#include "serf_private.h"
+
+#include "protocols/fcgi_buckets.h"
+#include "protocols/fcgi_protocol.h"
+
+struct serf_fcgi_stream_data_t
+{
+ int dummy;
+};
+
+serf_fcgi_stream_t *
+serf_fcgi__stream_create(serf_fcgi_protocol_t *h2,
+ apr_int32_t streamid,
+ apr_uint32_t lr_window,
+ apr_uint32_t rl_window,
+ serf_bucket_alloc_t *alloc)
+{
+ serf_fcgi_stream_t *stream = serf_bucket_mem_alloc(alloc,
+ sizeof(*stream));
+
+ stream->h2 = h2;
+ stream->alloc = alloc;
+
+ stream->next = stream->prev = NULL;
+
+ /* Delay creating this? */
+ stream->data = serf_bucket_mem_alloc(alloc, sizeof(*stream->data));
+
+ return stream;
+}
Propchange: serf/trunk/protocols/fcgi_stream.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: serf/trunk/serf.h
URL:
http://svn.apache.org/viewvc/serf/trunk/serf.h?rev=1714736&r1=1714735&r2=1714736&view=diff
==============================================================================
--- serf/trunk/serf.h (original)
+++ serf/trunk/serf.h Tue Nov 17 09:18:11 2015
@@ -611,7 +611,8 @@ void serf_connection_set_async_responses
typedef enum serf_connection_framing_type_t {
SERF_CONNECTION_FRAMING_TYPE_NONE = 0,
SERF_CONNECTION_FRAMING_TYPE_HTTP1,
- SERF_CONNECTION_FRAMING_TYPE_HTTP2
+ SERF_CONNECTION_FRAMING_TYPE_HTTP2,
+ SERF_CONNECTION_FRAMING_TYPE_FCGI
} serf_connection_framing_type_t;
/**
Modified: serf/trunk/serf_private.h
URL:
http://svn.apache.org/viewvc/serf/trunk/serf_private.h?rev=1714736&r1=1714735&r2=1714736&view=diff
==============================================================================
--- serf/trunk/serf_private.h (original)
+++ serf/trunk/serf_private.h Tue Nov 17 09:18:11 2015
@@ -685,6 +685,10 @@ serf_bucket_t *serf__bucket_log_wrapper_
void serf__http2_protocol_init(serf_connection_t *conn);
void serf__http2_protocol_init_server(serf_incoming_t *client);
+/* From fcgi_protocol.c: Initializes http2 state on connection */
+void serf__fcgi_protocol_init(serf_connection_t *conn);
+void serf__fcgi_protocol_init_server(serf_incoming_t *client);
+
typedef struct serf_hpack_table_t serf_hpack_table_t;
/* From http2_hpack_buckets.c */
Modified: serf/trunk/test/serf_httpd.c
URL:
http://svn.apache.org/viewvc/serf/trunk/test/serf_httpd.c?rev=1714736&r1=1714735&r2=1714736&view=diff
==============================================================================
--- serf/trunk/test/serf_httpd.c (original)
+++ serf/trunk/test/serf_httpd.c Tue Nov 17 09:18:11 2015
@@ -220,21 +220,39 @@ static apr_status_t client_accept(serf_c
apr_socket_t *insock,
apr_pool_t *pool)
{
- serf_incoming_t *incoming;
+ serf_incoming_t *client;
listener_ctx_t *lctx = accept_baton;
apr_pool_t *cctx_pool;
client_ctx_t *cctx;
+ apr_status_t status;
apr_pool_create(&cctx_pool, pool);
cctx = apr_pcalloc(cctx_pool, sizeof(*cctx));
cctx->pool = cctx_pool;
cctx->listener = lctx;
- return serf_incoming_create2(&incoming, ctx, insock,
- client_setup, cctx,
- client_closed, cctx,
- client_request_acceptor, cctx,
- pool);
+ status = serf_incoming_create2(&client, ctx, insock,
+ client_setup, cctx,
+ client_closed, cctx,
+ client_request_acceptor, cctx,
+ pool);
+ if (status)
+ return status;
+
+ if (lctx->proto && !strcmp(lctx->proto, "fcgi")) {
+ serf_incoming_set_framing_type(client,
+ SERF_CONNECTION_FRAMING_TYPE_FCGI);
+ }
+ else if (lctx->proto && !strcmp(lctx->proto, "h2c")) {
+ serf_incoming_set_framing_type(client,
+ SERF_CONNECTION_FRAMING_TYPE_HTTP2);
+ }
+ else if (lctx->proto && !strcmp(lctx->proto, "http1")) {
+ serf_incoming_set_framing_type(client,
+ SERF_CONNECTION_FRAMING_TYPE_HTTP1);
+ }
+
+ return status;
}