/** * Writes a response from srun to the client */ static int cse_write_response(stream_t *s, int len, request_rec *r) { while (len > 0) { int sublen; int writelen; int sentlen; if (s->read_length <= s->read_offset && cse_fill_buffer(s) < 0) return -1; sublen = s->read_length - s->read_offset; if (len < sublen) sublen = len; writelen = sublen; while (writelen > 0) { sentlen = ap_rwrite(s->read_buf + s->read_offset, writelen, r); /* * RSN-420. If the client fails, should still read data from the * server and complete that side of the socket. */ if (sentlen > 0) writelen -= sentlen; else writelen = 0; } s->read_offset += sublen; len -= sublen; } return 1; }
/** * Writes a response from srun to the client */ static int cse_write_response(stream_t *s, int len, request_rec *r) { while (len > 0) { int writelen; int sentlen; if (s->read_length <= s->read_offset && cse_fill_buffer(s) < 0) return -1; writelen = s->read_length - s->read_offset; if (len < writelen) writelen = len; while (writelen > 0) { sentlen = ap_rwrite(s->read_buf + s->read_offset, writelen, r); if (sentlen < 0) { cse_close(s, "write"); return -1; } writelen -= sentlen; s->read_offset += sentlen; len -= sentlen; } } return 1; }
/** * Copy data from the JVM to the browser. */ static int send_data(stream_t *s, request_rec *r) { int code = -1; char buf[8193]; char key[8193]; char value[8193]; int i; int channel; if (cse_fill_buffer(s) < 0) { return -1; } while (1) { int len; code = cse_read_byte(s); LOG(("%s:%d:send_data(): r-code %c\n", __FILE__, __LINE__, code)); switch (code) { case HMUX_CHANNEL: channel = hmux_read_len(s); LOG(("%s:%d:send_data(): r-channel %d\n", __FILE__, __LINE__, channel)); break; case HMUX_ACK: channel = hmux_read_len(s); LOG(("%s:%d:send_data(): r-ack %d\n", __FILE__, __LINE__, channel)); return code; case HMUX_STATUS: len = hmux_read_len(s); cse_read_limit(s, buf, sizeof(buf), len); for (i = 0; buf[i] && buf[i] != ' '; i++) { } i++; r->status = atoi(buf); r->status_line = apr_pstrdup(r->pool, buf); break; case HMUX_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); if (! strcasecmp(key, "content-type")) { r->content_type = apr_pstrdup(r->pool, value); apr_table_set(r->headers_out, key, value); } else apr_table_add(r->headers_out, key, value); break; case HMUX_META_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); break; case HMUX_DATA: len = hmux_read_len(s); if (cse_write_response(s, len, r) < 0) return HMUX_EXIT; break; case HMUX_FLUSH: len = hmux_read_len(s); ap_rflush(r); break; case CSE_SEND_HEADER: len = hmux_read_len(s); break; case HMUX_QUIT: case HMUX_EXIT: return code; default: if (code < 0) { return code; } len = hmux_read_len(s); cse_skip(s, len); break; } } }
/** * Copy data from the JVM to the browser. */ static int send_data(stream_t *s, request_rec *r, int ack, int *keepalive) { int code = HMUX_QUIT; char buf[8193]; char key[8193]; char value[8193]; int channel; int i; /* ap_reset_timeout(r); */ if (cse_fill_buffer(s) < 0) return -1; /* code = cse_read_byte(s); if (code != HMUX_CHANNEL) { r->status = 500; r->status_line = "Protocol error"; cse_close(s, "bad protocol"); return -1; } channel = hmux_read_len(s); */ do { int len; /* ap_reset_timeout(r); */ code = cse_read_byte(s); if (s->socket < 0) return -1; switch (code) { case HMUX_CHANNEL: channel = hmux_read_len(s); LOG(("channel %d\n", channel)); break; case HMUX_ACK: channel = hmux_read_len(s); LOG(("ack %d\n", channel)); break; case HMUX_STATUS: len = hmux_read_len(s); cse_read_limit(s, buf, sizeof(buf), len); for (i = 0; buf[i] && buf[i] != ' '; i++) { } buf[i] = 0; r->status = atoi(buf); buf[i] = ' '; i++; r->status_line = ap_pstrdup(r->pool, buf); break; case HMUX_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); if (! strcasecmp(key, "content-type")) r->content_type = ap_pstrdup(r->pool, value); else ap_table_add(r->headers_out, key, value); break; case HMUX_META_HEADER: len = hmux_read_len(s); cse_read_limit(s, key, sizeof(key), len); cse_read_string(s, value, sizeof(value)); break; case HMUX_DATA: len = hmux_read_len(s); if (cse_write_response(s, len, r) < 0) return -1; break; case HMUX_FLUSH: len = hmux_read_len(s); ap_rflush(r); break; case CSE_KEEPALIVE: len = hmux_read_len(s); *keepalive = 1; break; case CSE_SEND_HEADER: len = hmux_read_len(s); ap_send_http_header(r); break; case -1: break; case HMUX_QUIT: case HMUX_EXIT: break; default: len = hmux_read_len(s); cse_skip(s, len); break; } } while (code > 0 && code != HMUX_QUIT && code != HMUX_EXIT && code != ack); return code; }