mirror of
https://github.com/moparisthebest/spdylay
synced 2024-11-05 00:55:07 -05:00
Added spdylay_session_on_ctrl_recv_parse_error_callback.
This callback function is invoked when the received frame data could not be parsed correctly. Added debug output using this callback to spdycat.
This commit is contained in:
parent
b7429e7c2d
commit
171bede1fa
@ -348,6 +348,8 @@ int run(char **uris, int n)
|
||||
callbacks.on_ctrl_recv_callback = on_ctrl_recv_callback3;
|
||||
callbacks.on_data_recv_callback = on_data_recv_callback;
|
||||
callbacks.on_ctrl_send_callback = on_ctrl_send_callback3;
|
||||
callbacks.on_ctrl_recv_parse_error_callback =
|
||||
on_ctrl_recv_parse_error_callback;
|
||||
} else {
|
||||
callbacks.on_ctrl_recv_callback = on_ctrl_recv_callback2;
|
||||
callbacks.on_ctrl_send_callback = on_ctrl_send_callback2;
|
||||
|
@ -407,6 +407,34 @@ void on_ctrl_recv_callback
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const char* spdylay_strerror(int error_code)
|
||||
{
|
||||
return "UNKNOWN";
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void on_ctrl_recv_parse_error_callback(spdylay_session *session,
|
||||
spdylay_frame_type type,
|
||||
const uint8_t *head,
|
||||
size_t headlen,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen,
|
||||
int error_code, void *user_data)
|
||||
{
|
||||
size_t i;
|
||||
print_timer();
|
||||
printf(" recv %s frame: Parse error [%s]\n", ctrl_names[type-1],
|
||||
spdylay_strerror(error_code));
|
||||
print_frame_attr_indent();
|
||||
printf("Header dump: ");
|
||||
for(i = 0; i < headlen; ++i) {
|
||||
printf("%02X ", head[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void on_ctrl_send_callback
|
||||
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
|
||||
void *user_data)
|
||||
|
@ -85,6 +85,14 @@ void on_ctrl_recv_callback
|
||||
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
|
||||
void *user_data);
|
||||
|
||||
void on_ctrl_recv_parse_error_callback(spdylay_session *session,
|
||||
spdylay_frame_type type,
|
||||
const uint8_t *head,
|
||||
size_t headlen,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen,
|
||||
int error_code, void *user_data);
|
||||
|
||||
void on_ctrl_send_callback
|
||||
(spdylay_session *session, spdylay_frame_type type, spdylay_frame *frame,
|
||||
void *user_data);
|
||||
|
@ -957,6 +957,27 @@ typedef void (*spdylay_on_stream_close_callback)
|
||||
typedef void (*spdylay_on_request_recv_callback)
|
||||
(spdylay_session *session, int32_t stream_id, void *user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* Callback function invoked when the received control frame octets
|
||||
* could not be parsed correctly. The |type| indicates the type of
|
||||
* received control frame. The |head| is the pointer to the header of
|
||||
* the received frame. The |headlen| is the length of the
|
||||
* |head|. According to the SPDY spec, the |headlen| is always 8. In
|
||||
* other words, the |head| is the first 8 bytes of the received frame.
|
||||
* The |payload| is the pointer to the data portion of the received
|
||||
* frame. The |payloadlen| is the length of the |payload|. This is
|
||||
* the data after the length field. The |error_code| is one of the
|
||||
* error code defined in :enum:`spdylay_error` and indicates the
|
||||
* error.
|
||||
*/
|
||||
typedef void (*spdylay_on_ctrl_recv_parse_error_callback)
|
||||
(spdylay_session *session, spdylay_frame_type type,
|
||||
const uint8_t *head, size_t headlen,
|
||||
const uint8_t *payload, size_t payloadlen,
|
||||
int error_code, void *user_data);
|
||||
|
||||
#define SPDYLAY_MAX_SCHEME 255
|
||||
#define SPDYLAY_MAX_HOSTNAME 255
|
||||
|
||||
@ -1117,6 +1138,11 @@ typedef struct {
|
||||
* certificate.
|
||||
*/
|
||||
spdylay_get_credential_cert get_credential_cert;
|
||||
/**
|
||||
* Callback function invoked when the received control frame octets
|
||||
* could not be parsed correctly.
|
||||
*/
|
||||
spdylay_on_ctrl_recv_parse_error_callback on_ctrl_recv_parse_error_callback;
|
||||
} spdylay_session_callbacks;
|
||||
|
||||
/**
|
||||
@ -1375,6 +1401,9 @@ int spdylay_session_send(spdylay_session *session);
|
||||
* invalid,
|
||||
* :member:`spdylay_session_callbacks.on_invalid_ctrl_recv_callback`
|
||||
* is invoked.
|
||||
* 3.4. If the received frame could not be unpacked correctly,
|
||||
* :member:`spdylay_session_callbacks.on_ctrl_recv_parse_error_callback`
|
||||
* is invoked.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
|
@ -2004,6 +2004,23 @@ int spdylay_session_on_headers_received(spdylay_session *session,
|
||||
return r;
|
||||
}
|
||||
|
||||
static void spdylay_session_handle_parse_error(spdylay_session *session,
|
||||
spdylay_frame_type type,
|
||||
int error_code)
|
||||
{
|
||||
if(session->callbacks.on_ctrl_recv_parse_error_callback) {
|
||||
session->callbacks.on_ctrl_recv_parse_error_callback
|
||||
(session,
|
||||
type,
|
||||
session->iframe.headbuf,
|
||||
sizeof(session->iframe.headbuf),
|
||||
session->iframe.buf,
|
||||
session->iframe.len,
|
||||
error_code,
|
||||
session->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/* For errors, this function only returns FATAL error. */
|
||||
static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
{
|
||||
@ -2038,6 +2055,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
SPDYLAY_PROTOCOL_ERROR);
|
||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2064,6 +2082,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
SPDYLAY_PROTOCOL_ERROR);
|
||||
spdylay_frame_syn_reply_free(&frame.syn_reply);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2077,6 +2096,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
r = spdylay_session_on_rst_stream_received(session, &frame);
|
||||
spdylay_frame_rst_stream_free(&frame.rst_stream);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2090,6 +2110,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
r = spdylay_session_on_settings_received(session, &frame);
|
||||
spdylay_frame_settings_free(&frame.settings);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2105,6 +2126,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
r = spdylay_session_on_ping_received(session, &frame);
|
||||
spdylay_frame_ping_free(&frame.ping);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2118,6 +2140,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
r = spdylay_session_on_goaway_received(session, &frame);
|
||||
spdylay_frame_goaway_free(&frame.goaway);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2144,6 +2167,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
SPDYLAY_PROTOCOL_ERROR);
|
||||
spdylay_frame_headers_free(&frame.headers);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2157,6 +2181,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
r = spdylay_session_on_window_update_received(session, &frame);
|
||||
spdylay_frame_window_update_free(&frame.window_update);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
@ -2170,6 +2195,7 @@ static int spdylay_session_process_ctrl_frame(spdylay_session *session)
|
||||
r = spdylay_session_on_credential_received(session, &frame);
|
||||
spdylay_frame_credential_free(&frame.credential);
|
||||
} else if(spdylay_is_non_fatal(r)) {
|
||||
spdylay_session_handle_parse_error(session, type, r);
|
||||
r = spdylay_session_fail_session(session, SPDYLAY_GOAWAY_PROTOCOL_ERROR);
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user