comparison src/http/ngx_http_spdy.c @ 5527:f3f7b72ca6e9

SPDY: proper handling of all RST_STREAM statuses. Previously, only stream CANCEL and INTERNAL_ERROR were handled right.
author Valentin Bartenev <vbart@nginx.com>
date Wed, 22 Jan 2014 04:58:19 +0400
parents 2c6f82c0cec2
children d5de6c25b759
comparison
equal deleted inserted replaced
5526:2c6f82c0cec2 5527:f3f7b72ca6e9
1225 u_char *end) 1225 u_char *end)
1226 { 1226 {
1227 ngx_uint_t sid, status; 1227 ngx_uint_t sid, status;
1228 ngx_event_t *ev; 1228 ngx_event_t *ev;
1229 ngx_connection_t *fc; 1229 ngx_connection_t *fc;
1230 ngx_http_request_t *r;
1231 ngx_http_spdy_stream_t *stream; 1230 ngx_http_spdy_stream_t *stream;
1232 1231
1233 if (end - pos < NGX_SPDY_RST_STREAM_SIZE) { 1232 if (end - pos < NGX_SPDY_RST_STREAM_SIZE) {
1234 return ngx_http_spdy_state_save(sc, pos, end, 1233 return ngx_http_spdy_state_save(sc, pos, end,
1235 ngx_http_spdy_state_rst_stream); 1234 ngx_http_spdy_state_rst_stream);
1236 } 1235 }
1237 1236
1238 if (sc->length != NGX_SPDY_RST_STREAM_SIZE) { 1237 if (sc->length != NGX_SPDY_RST_STREAM_SIZE) {
1239 /* TODO logging */ 1238 ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
1239 "client sent RST_STREAM frame with incorrect length %uz",
1240 sc->length);
1241
1240 return ngx_http_spdy_state_protocol_error(sc); 1242 return ngx_http_spdy_state_protocol_error(sc);
1241 } 1243 }
1242 1244
1243 sid = ngx_spdy_frame_parse_sid(pos); 1245 sid = ngx_spdy_frame_parse_sid(pos);
1244 1246
1249 pos += sizeof(uint32_t); 1251 pos += sizeof(uint32_t);
1250 1252
1251 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0, 1253 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1252 "spdy RST_STREAM sid:%ui st:%ui", sid, status); 1254 "spdy RST_STREAM sid:%ui st:%ui", sid, status);
1253 1255
1256 stream = ngx_http_spdy_get_stream_by_id(sc, sid);
1257 if (stream == NULL) {
1258 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
1259 "unknown stream, probably it has been closed already");
1260 return ngx_http_spdy_state_complete(sc, pos, end);
1261 }
1262
1263 stream->in_closed = 1;
1264 stream->out_closed = 1;
1265
1266 fc = stream->request->connection;
1267 fc->error = 1;
1254 1268
1255 switch (status) { 1269 switch (status) {
1256 1270
1257 case NGX_SPDY_PROTOCOL_ERROR: 1271 case NGX_SPDY_CANCEL:
1258 /* TODO logging */ 1272 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
1259 return ngx_http_spdy_state_protocol_error(sc); 1273 "client canceled stream %ui", sid);
1260
1261 case NGX_SPDY_INVALID_STREAM:
1262 /* TODO */
1263 break; 1274 break;
1264 1275
1265 case NGX_SPDY_REFUSED_STREAM: 1276 case NGX_SPDY_INTERNAL_ERROR:
1266 /* TODO */ 1277 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
1278 "client terminated stream %ui because of internal error",
1279 sid);
1267 break; 1280 break;
1268 1281
1269 case NGX_SPDY_UNSUPPORTED_VERSION: 1282 default:
1270 /* TODO logging */ 1283 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
1271 return ngx_http_spdy_state_protocol_error(sc); 1284 "client terminated stream %ui with status %ui",
1272 1285 sid, status);
1273 case NGX_SPDY_CANCEL:
1274 case NGX_SPDY_INTERNAL_ERROR:
1275 stream = ngx_http_spdy_get_stream_by_id(sc, sid);
1276 if (stream == NULL) {
1277 /* TODO false cancel */
1278 break;
1279 }
1280
1281 stream->in_closed = 1;
1282 stream->out_closed = 1;
1283
1284 r = stream->request;
1285
1286 fc = r->connection;
1287 fc->error = 1;
1288
1289 ev = fc->read;
1290 ev->handler(ev);
1291
1292 break; 1286 break;
1293 1287 }
1294 case NGX_SPDY_FLOW_CONTROL_ERROR: 1288
1295 /* TODO logging */ 1289 ev = fc->read;
1296 return ngx_http_spdy_state_protocol_error(sc); 1290 ev->handler(ev);
1297
1298 default:
1299 /* TODO */
1300 return ngx_http_spdy_state_protocol_error(sc);
1301 }
1302 1291
1303 return ngx_http_spdy_state_complete(sc, pos, end); 1292 return ngx_http_spdy_state_complete(sc, pos, end);
1304 } 1293 }
1305 1294
1306 1295