in native/common/jk_ajp12_worker.c [557:716]
static int ajpv12_handle_response(ajp12_endpoint_t * p,
jk_ws_service_t *s, jk_log_context_t *l)
{
int status = 200;
char *reason = NULL;
char **names = NULL;
char **values = NULL;
int headers_capacity = 0;
int headers_len = 0;
int write_to_ws;
jk_log(l, JK_LOG_DEBUG, "Into ajpv12_handle_response");
/*
* Read headers ...
*/
while (1) {
char *line = NULL;
char *name = NULL;
char *value = NULL;
#ifdef _MT_CODE_PTHREAD
char *lasts;
#endif
if (!jk_sb_gets(&p->sb, &line)) {
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, error reading header line");
return JK_FALSE;
}
#if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX)
jk_xlate_from_ascii(line, strlen(line));
#endif
jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s", line);
if (0 == strlen(line)) {
jk_log(l, JK_LOG_DEBUG,
"ajpv12_handle_response, headers are done");
break; /* Empty line -> end of headers */
}
name = line;
while (jk_isspace(*name) && *name) {
name++; /* Skip leading white chars */
}
if (!*name) { /* Empty header name */
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, empty header name");
return JK_FALSE;
}
if (!(value = strchr(name, ':'))) {
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, no value supplied");
return JK_FALSE; /* No value !!! */
}
*value = '\0';
value++;
while (jk_isspace(*value) && *value) {
value++; /* Skip leading white chars */
}
if (!*value) { /* Empty header value */
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, empty header value");
return JK_FALSE;
}
jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s=%s", name,
value);
if (0 == strcmp("Status", name)) {
#ifdef _MT_CODE_PTHREAD
char *numeric = strtok_r(value, " \t", &lasts);
#else
char *numeric = strtok(value, " \t");
#endif
status = atoi(numeric);
if (status < 100 || status > 999) {
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, invalid status code");
return JK_FALSE;
}
#ifdef _MT_CODE_PTHREAD
reason = jk_pool_strdup(s->pool, strtok_r(NULL, " \t", &lasts));
#else
reason = jk_pool_strdup(s->pool, strtok(NULL, " \t"));
#endif
}
else {
if (headers_capacity == headers_len) {
jk_log(l, JK_LOG_DEBUG,
"ajpv12_handle_response, allocating header arrays");
names =
(char **)jk_pool_realloc(s->pool,
sizeof(char *) *
(headers_capacity + 5), names,
sizeof(char *) *
headers_capacity);
values =
(char **)jk_pool_realloc(s->pool,
sizeof(char *) *
(headers_capacity + 5), values,
sizeof(char *) *
headers_capacity);
if (!values || !names) {
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, malloc error");
return JK_FALSE;
}
headers_capacity = headers_capacity + 5;
}
names[headers_len] = jk_pool_strdup(s->pool, name);
values[headers_len] = jk_pool_strdup(s->pool, value);
headers_len++;
}
}
jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, starting response");
if (!s->start_response(s,
status,
reason,
(const char *const *)names,
(const char *const *)values, headers_len)) {
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, error starting response");
return JK_FALSE;
}
jk_log(l, JK_LOG_DEBUG,
"ajpv12_handle_response, reading response body");
/*
* Read response body
*/
write_to_ws = JK_TRUE;
while (1) {
unsigned to_read = READ_BUF_SIZE;
unsigned acc = 0;
char *buf = NULL;
if (!jk_sb_read(&p->sb, &buf, to_read, &acc)) {
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, error reading from ");
return JK_FALSE;
}
if (!acc) {
jk_log(l, JK_LOG_DEBUG,
"ajpv12_handle_response, response body is done");
break;
}
if (write_to_ws) {
if (!s->write(s, buf, acc)) {
jk_log(l, JK_LOG_ERROR,
"ajpv12_handle_response, error writing back to server");
write_to_ws = JK_FALSE;
}
}
}
jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response done");
return JK_TRUE;
}