📄 protocol.cpp
字号:
if (s->read_offset >= s->read_length) {
if (cse_fill_buffer(s) < 0)
return -1;
}
sublen = s->read_length - s->read_offset;
if (len < sublen)
sublen = len;
s->read_buf[s->read_length] = 0;
unsigned long writelen = sublen;
while (writelen > 0) {
unsigned long sentlen = writelen;
if (! r->WriteClient(r->ConnID, s->read_buf + s->read_offset, &sentlen, HSE_IO_SYNC) ||
sentlen <= 0) {
cse_close(s, "response");
return -1;
}
writelen -= sentlen;
s->read_offset += sentlen;
}
len -= sublen;
}
return 1;
}
static int
cse_copy_results(stream_t *s, EXTENSION_CONTROL_BLOCK *r, config_t *config)
{
char headers[32 * 1024];
char status[8192];
char *status_code_ptr = status; char *status_head = status;
char *status_end = status_head;
char *header_ptr = headers;
char *header_end = header_ptr + sizeof(headers) - 256;
int code;
*header_ptr = 0;
do {
int i;
int l1, l2, l3;
int read_len;
unsigned long size;
code = cse_read_byte(s);
l1 = cse_read_byte(s) & 0xff;
l2 = cse_read_byte(s) & 0xff;
l3 = cse_read_byte(s);
read_len = (l1 << 16) + (l2 << 8) + (l3 & 0xff);
if (l3 < 0 || s->socket < 0)
return -1;
LOG(("code %c(%d) %d\n", code, code, read_len));
switch (code) {
case CSE_DATA:
if (cse_write_response(s, read_len, r) < 0)
code = -1;
break;
case CSE_STATUS:
cse_read_limit(s, status, sizeof(status), read_len);
for (status_code_ptr = status; *status_code_ptr && *status_code_ptr != ' '; status_code_ptr++) {
}
for (; *status_code_ptr == ' '; status_code_ptr++) {
}
for (status_head = status_code_ptr; *status_head && *status_head != ' '; status_head++) {
} status_end = status + read_len; break;
case CSE_HEADER:
header_ptr += cse_read_limit(s, header_ptr,
header_end - header_ptr,
read_len);
*header_ptr++ = ':';
*header_ptr++ = ' ';
code = cse_read_byte(s);
l1 = cse_read_byte(s) & 0xff;
l2 = cse_read_byte(s) & 0xff;
l3 = cse_read_byte(s);
read_len = (l1 << 16) + (l2 << 8) + (l3 & 0xff);
if (l3 < 0 || s->socket < 0)
return -1;
header_ptr += cse_read_limit(s, header_ptr,
header_end - header_ptr,
read_len);
*header_ptr++ = '\r';
*header_ptr++ = '\n';
break;
case CSE_SEND_HEADER:
*header_ptr++ = '\r';
*header_ptr++ = '\n';
*header_ptr++ = 0;
size = header_ptr - headers;
{
HSE_SEND_HEADER_EX_INFO info;
unsigned long info_size = sizeof(info);
int statusCode = atoi(status_code_ptr);
memset(&info, 0, sizeof(info));
info.cchStatus = status_end - status_code_ptr; info.cchHeader = header_ptr - headers;
info.pszHeader = headers;
info.pszStatus = status_code_ptr;
info.fKeepConn = 0; // statusCode < 400 || statusCode == 404;
/*
r->dwHttpStatusCode = atoi(status_ptr);
r->ServerSupportFunction(r->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status, &size, (unsigned long *) headers);
*/
r->dwHttpStatusCode = statusCode;
r->ServerSupportFunction(r->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &info, &info_size, 0);
}
break;
default:
if (code < 0 || read_len < 0 || read_len > 8192) {
code = -1;
break;
}
cse_skip(s, read_len);
break;
}
} while (code > 0 && code != CSE_END && code != CSE_ACK && code != CSE_CLOSE);
return code;
}
static void
cse_get_ip(EXTENSION_CONTROL_BLOCK *r, char *ip, unsigned long length)
{
ip[0] = 0;
if (r->GetServerVariable(r->ConnID, "REMOTE_ADDR", ip, &length) && length >= 0)
ip[length] = 0;
else
ip[0] = 0;
}
static int
get_session_index(config_t *config, EXTENSION_CONTROL_BLOCK *r, int *backup)
{
char buf[16384];
unsigned long i = 0;
unsigned long len = sizeof(buf);
int session;
if (r->GetServerVariable(r->ConnID, "HTTP_COOKIE", buf, &len)) {
session = cse_session_from_string(buf, config->session_cookie, backup);
LOG(("session %d %s\n", session, buf));
if (session >= 0)
return session;
}
len = sizeof(buf);
buf[0] = 0;
if (! r->GetServerVariable(r->ConnID, "PATH_INFO", buf, &len))
return -1;
buf[len] = 0;
return cse_session_from_string(buf, config->session_url_prefix, backup);
}
static int
get_session_from_raw(config_t *config, EXTENSION_CONTROL_BLOCK *r, int *backup)
{
char buf[16384];
unsigned long i = 0;
unsigned long len = sizeof(buf);
int session;
if (! r->GetServerVariable(r->ConnID, "ALL_RAW", buf, &len))
return -1;
while (i < len) {
int head = i + 5;
int tail;
i = head;
for (; i < len && buf[i] != ':'; i++) {
}
tail = i;
for (i++; i < len && buf[i] != '\r' && buf[i] != '\n'; i++) {
}
if (head >= tail)
continue;
buf[tail] = 0;
buf[i] = 0;
if (stricmp(buf + head, "cookie"))
continue;
session = cse_session_from_string(buf + tail + 1, config->session_cookie, backup);
if (session >= 0)
return session;
}
return -1;
}
static int
write_request(stream_t *s, EXTENSION_CONTROL_BLOCK *r, config_t *config)
{
int code;
int backup_index = 0;
int session_index = get_session_index(config, r, &backup_index);
srun_t *srun;
DWORD now = GetTickCount() / 1000;
if (! cse_open_connection(s, config, session_index, backup_index, now, 0))
return connection_error(config, r);
srun = s->srun->srun;
cse_lock(srun->lock);
srun->active_sockets++;
cse_unlock(srun->lock);
int isHttp11 = write_env(s, r);
write_headers(s, r);
// read post data
char buf[BUF_LENGTH + 8];
int isFirst = 1;
unsigned long totalLen = 0;
while (totalLen < r->cbTotalBytes) {
unsigned long len = BUF_LENGTH;
if (r->cbAvailable > 0) {
if (len > r->cbAvailable)
len = r->cbAvailable;
memcpy(buf, r->lpbData + totalLen, len);
r->cbAvailable -= len;
}
else if (! r->ReadClient(r->ConnID, buf, &len) || len <= 0)
break;
totalLen += len;
cse_write_packet(s, CSE_DATA, buf, len);
if (! isFirst) {
code = cse_copy_results(s, r, config);
if (code < 0 || code == CSE_END || code == CSE_CLOSE)
break;
}
isFirst = 0;
}
cse_write_packet(s, CSE_END, 0, 0);
code = cse_copy_results(s, r, config);
if (code == CSE_END)
cse_recycle(s, now);
else
cse_close(s, "write");
cse_lock(srun->lock);
srun->active_sockets--;
cse_unlock(srun->lock);
return code == CSE_END || code == CSE_CLOSE;
}
static int g_count;
static void
jvm_status(config_t *config, EXTENSION_CONTROL_BLOCK *r)
{
int i;
stream_t s;
cse_printf(r, "<p><center><table border=2 width=\"80%%\">\n");
cse_printf(r, "<tr><th>Host</th>\n");
cse_printf(r, " <th>Active</th>\n");
cse_printf(r, " <th>Pooled</th>\n");
cse_printf(r, " <th>Connect<br>Timeout</th>\n");
cse_printf(r, " <th>Live<br>Time</th>\n");
cse_printf(r, " <th>Dead<br>Time</th>\n");
cse_printf(r, "</tr>\n");
for (i = 0; i < config->srun_size; i++) {
srun_item_t *srun_item = config->srun_list + i;
srun_t *srun = srun_item->srun;
int port;
int pool_count;
char group_buf[1024];
if (! srun)
continue;
port = srun->port;
pool_count = ((srun->conn_head - srun->conn_tail + CONN_POOL_SIZE) %
CONN_POOL_SIZE);
cse_printf(r, "<tr>");
if (srun_item->id && *srun_item->id &&
srun_item->group && *srun_item->group)
sprintf(group_buf, " (%s, %s)", srun_item->id, srun_item->group);
else if (srun_item->group && *srun_item->group)
sprintf(group_buf, " (%s)", srun_item->group);
else if (srun_item->id && *srun_item->id)
sprintf(group_buf, " (%s)", srun_item->id);
else
group_buf[0] = 0;
if (! cse_open(&s, config, srun_item, 0, 1)) {
cse_printf(r, "<td bgcolor='#ff6666'>%d. %s:%d%s (down)</td>",
srun_item->session + 1,
srun->hostname ? srun->hostname : "localhost",
port, srun_item->is_backup ? "*" : "");
}
else {
cse_printf(r, "<td bgcolor='#66ff66'>%d. %s:%d%s (ok)</td>",
srun_item->session + 1,
srun->hostname ? srun->hostname : "localhost",
port, srun_item->is_backup ? "*" : "");
}
cse_close(&s, "caucho-status");
cse_printf(r, "<td align=right>%d</td><td align=right>%d</td>",
srun->active_sockets, pool_count);
cse_printf(r, "<td align=right>%d</td><td align=right>%d</td><td align=right>%d</td>",
srun->connect_timeout, srun->live_time, srun->dead_time);
cse_printf(r, "</tr>\n");
}
cse_printf(r, "</table></center>\n");
}
static void
cse_caucho_status(config_t *config, EXTENSION_CONTROL_BLOCK *r)
{
web_app_t *app;
location_t *loc;
char *headers = "200 OK\r\nContent-Type: text/html";
unsigned long size = strlen(headers);
if (config->disable_caucho_status)
return;
r->ServerSupportFunction(r->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, headers, &size, 0);
cse_printf(r, "<html><title>Status : Caucho Servlet Engine</title>\n");
cse_printf(r, "<body bgcolor=white>\n");
cse_printf(r, "<h1>Status : Caucho Servlet Engine</h1>\n");
if (config->path)
cse_printf(r, "<b>Config:</b> %s<br>", config->path);
if (config->resin_home)
cse_printf(r, "<b>Resin-Home:</b> %s<br>", config->resin_home);
if (config->error) {
cse_printf(r, "<b><font color=\"red\">%s</font></b><br>",
config->error);
}
jvm_status(config, r);
cse_printf(r, "<p><center><table border=2 cellspacing=0 cellpadding=2 width=\"80%%\">\n");
cse_printf(r, "<tr><th width='50%'>Host\n");
cse_printf(r, " <th>url-pattern\n");
app = config ? config->applications : 0;
for (; app; app = app->next) {
char port[16];
char *host = 0;
if (app->host_alias_length > 0 && app->host_aliases[0]->port > 0)
sprintf(port, ":%d", app->host_aliases[0]->port);
else
port[0] = 0;
if (app->host_alias_length > 0)
host = app->host_aliases[0]->host;
for (loc = app->locations; loc; loc = loc->next) {
cse_printf(r, "<tr bgcolor='#ffcc66'><td>%s%s%s<td>%s%s%s%s</tr>\n",
host ? host : "", port,
*app->prefix ? app->prefix : "/",
loc->prefix,
! loc->is_exact && ! loc->suffix ? "/*" :
loc->suffix && loc->prefix[0] ? "/" : "",
loc->suffix ? "*" : "",
loc->suffix ? loc->suffix : "");
}
}
cse_printf(r, "</table></center>\n");
cse_printf(r, "<hr/><em>%s</em>\n", VERSION);
cse_printf(r, "</body></html>\n");
}
int
cse_handle_request(config_t *config, EXTENSION_CONTROL_BLOCK *r)
{
char host[1024];
char port_buf[80];
int port = 0;
char url[8192];
char *ptr = url;
unsigned long size;
size = sizeof(host);
host[0] = 0;
r->GetServerVariable(r->ConnID, "SERVER_NAME", host, &size);
size = sizeof(port_buf);
if (r->GetServerVariable(r->ConnID, "SERVER_PORT", port_buf, &size) && size > 0) {
port = atoi(port_buf);
}
size = sizeof(url);
url[0] = 0;
if (r->GetServerVariable(r->ConnID, "PATH_INFO", url, &size) && size > 0 && url[0]) {
url[size] = 0;
if (! strcmp(url, "/caucho-status")) {
cse_caucho_status(config, r);
return 1;
}
else if (! cse_match_request(config, host, port, ptr, 0))
return cse_error(config, r);
}
else
return cse_error(config, r);
stream_t s;
return write_request(&s, r, config);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -