📄 protocol.cpp
字号:
sublen) < 0) return -1; len -= sublen; s->read_offset += sublen; } return 1;}static char *fill_chunk(char *buf, int size){ int i; for (i = 12; i >= 0; i -= 4) { int digit = (size >> i) & 0xf; if (digit > 9) *buf++ = 'a' + digit - 10; else *buf++ = '0' + digit; } *buf++ = '\r'; *buf++ = '\n'; *buf = 0; return buf;}static intsend_data(stream_t *s, EXTENSION_CONTROL_BLOCK *r, config_t *config, int ack, int *p_http11, int *p_is_first){ char headers[32 * 1024]; char status[BUF_LENGTH]; char chunk[16]; char *status_ptr = status; char *header_ptr = headers; char *header_end = header_ptr + sizeof(headers) - 256; int code; int http11 = *p_http11; chunk[0] = '\r'; chunk[1] = '\n'; *header_ptr = 0; do { int read_len; unsigned long size; code = cse_read_byte(s); if (code < 0 || s->socket < 0) { if (status == status_ptr) connection_error(s->config, r); return -1; } LOG(("code %c(%d)\n", code, code)); switch (code) { case HMUX_YIELD: break; case HMUX_CHANNEL: read_len = hmux_read_len(s); break; case HMUX_ACK: read_len = hmux_read_len(s); break; case HMUX_DATA: read_len = hmux_read_len(s); if (http11) { char *tail = fill_chunk(chunk + 2, read_len); if (*p_is_first) write_client_buffer(r, chunk + 2, tail - chunk - 2); else write_client_buffer(r, chunk, tail - chunk); *p_is_first = 0; } if (cse_write_response(s, read_len, r) < 0) code = -1; break; case HMUX_STATUS: read_len = hmux_read_len(s); cse_read_limit(s, status, sizeof(status), read_len); if (status[0] != '2') { http11 = 0; *p_http11 = 0; } status_ptr = status + read_len; break; case HMUX_META_HEADER: read_len = hmux_read_len(s); cse_skip(s, read_len); code = cse_read_byte(s); read_len = hmux_read_len(s); cse_skip(s, read_len); break; case HMUX_HEADER: read_len = hmux_read_len(s); header_ptr += cse_read_limit(s, header_ptr, header_end - header_ptr, read_len); *header_ptr++ = ':'; *header_ptr++ = ' '; code = cse_read_byte(s); read_len = hmux_read_len(s); if (read_len < 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: read_len = hmux_read_len(s); cse_skip(s, read_len); if (http11) { char chunked[] = "Transfer-Encoding: chunked\r\n"; strcpy(header_ptr, chunked); header_ptr += sizeof(chunked) - 1; } *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_ptr); memset(&info, 0, sizeof(info)); info.cchStatus = status_ptr - status; info.cchHeader = header_ptr - headers; info.pszHeader = headers; info.pszStatus = status; /* #1802, #2150 */ info.fKeepConn = http11; /* 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; case HMUX_QUIT: case HMUX_EXIT: if (http11) { write_client_buffer(r, "\r\n0\r\n\r\n", 7); } return code; default: if (code < 0) { code = -1; connection_error(config, r); break; } read_len = hmux_read_len(s); if (read_len < 0 || read_len > BUF_LENGTH) { code = -1; break; } cse_skip(s, read_len); break; } } while (code > 0 && code != HMUX_QUIT && code != HMUX_EXIT && code != ack); return code;}static voidcse_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 intget_session_index(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, "JSESSIONID=", 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, "jsessionid=", backup);}static intget_session_from_raw(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, "JSESSIONID=", backup); if (session >= 0) return session; } return -1;}static intwrite_request(stream_t *s, EXTENSION_CONTROL_BLOCK *r, config_t *config, char *host_name, int port){ int backup_index = 0; int session_index = get_session_index(r, &backup_index); srun_t *srun; resin_host_t *host; DWORD now = GetTickCount() / 1000; host = cse_match_host(config, host_name, port, now); if (! host || ! cse_open_connection(s, &host->cluster, session_index, backup_index, now, 0)) return connection_error(config, r); srun = s->cluster_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 ack_size = s->cluster_srun->srun->send_buffer_size; int send_length = 0; unsigned long totalLen = 0; int code = HMUX_ACK; int is_first = 1; //while (totalLen < r->cbTotalBytes) { while (true) { 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->cbTotalBytes <= 0) break; else if (r->cbTotalBytes <= totalLen) break; else if (! r->ReadClient(r->ConnID, buf, &len) || len <= 0) break; totalLen += len; send_length += len; LOG(("send-post %d\n", len)); cse_write_packet(s, CSE_DATA, buf, len); if (ack_size <= send_length) { send_length = 0; cse_write_byte(s, HMUX_YIELD); code = send_data(s, r, config, CSE_ACK, &isHttp11, &is_first); if (code < 0 || code == HMUX_QUIT || code == HMUX_EXIT) break; } } LOG(("quit\n")); cse_write_byte(s, HMUX_QUIT); code = send_data(s, r, config, HMUX_QUIT, &isHttp11, &is_first); if (code == HMUX_QUIT) cse_recycle(s, now); else cse_close(s, "write"); cse_lock(srun->lock); srun->active_sockets--; cse_unlock(srun->lock); return code == HMUX_QUIT || code == HMUX_EXIT;}static int g_count;static voidjvm_status(cluster_t *cluster, EXTENSION_CONTROL_BLOCK *r){ int i; stream_t s; cse_printf(r, "<p><center><table border='2' width=\"90%%\">\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, " <th>Read<br>Timeout</th>\n"); cse_printf(r, "</tr>\n"); for (; cluster; cluster = cluster->next) { for (i = 0; i < cluster->srun_capacity; i++) { cluster_srun_t *cluster_srun = cluster->srun_list + i; srun_t *srun = cluster_srun->srun; int port; int pool_count; 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 (! cse_open(&s, cluster, cluster_srun, 0, 0)) { cse_printf(r, "<td bgcolor='#ff6666'>%d. %s:%d%s (down)</td>", cluster_srun->index + 1, srun->hostname ? srun->hostname : "localhost", port, cluster_srun->is_backup ? "*" : ""); } else { cse_printf(r, "<td bgcolor='#66ff66'>%d. %s:%d%s (ok)</td>", cluster_srun->index + 1, srun->hostname ? srun->hostname : "localhost", port, cluster_srun->is_backup ? "*" : ""); } /* This needs to be close, because cse_open doesn't use recycle. */ cse_close(&s, "caucho-status"); LOG(("close\n")); 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, "<td align=right>%d</td>", srun->read_timeout); cse_printf(r, "</tr>\n"); } } cse_printf(r, "</table></center>\n");}static voidcse_caucho_status(config_t *config, EXTENSION_CONTROL_BLOCK *r){ resin_host_t *host; web_app_t *app; location_t *loc; char *headers = "200 OK\r\nContent-Type: text/html"; unsigned long size = strlen(headers); DWORD now = GetTickCount() / 1000; if (! config->enable_caucho_status) return; r->ServerSupportFunction(r->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, headers, &size, 0); cse_printf(r, "<html><title>Status : Resin ISAPI Plugin</title>\n"); cse_printf(r, "<body bgcolor=white>\n"); cse_printf(r, "<h1>Status : Resin ISAPI Plugin</h1>\n"); if (config->error) { cse_printf(r, "<b><font color=\"red\">%s</font></b><br>", config->error); } cse_printf(r, "<h2>Configuration Cluster</h2>\n"); jvm_status(&config->config_cluster, r); host = config ? config->hosts : 0; for (; host; host = host->next) { if (host != host->canonical) continue; /* check updates as appropriate */ cse_match_host(config, host->name, host->port, now); if (! *host->name) cse_printf(r, "<h2>Default Virtual Host</h2>\n"); else if (host->port) cse_printf(r, "<h2>Virtual Host: %s:%d</h2>\n", host->name, host->port); else cse_printf(r, "<h2>Virtual Host: %s</h2>\n", host->name); jvm_status(&host->cluster, r); cse_printf(r, "<p><center><table border='2' cellspacing='0' cellpadding='2' width='90%%'>\n"); cse_printf(r, "<tr><th>web-app\n"); cse_printf(r, " <th>url-pattern\n"); app = host->applications; for (; app; app = app->next) { for (loc = app->locations; loc; loc = loc->next) { cse_printf(r, "<tr bgcolor='#ffcc66'><td>%s<td>%s%s%s%s%s</tr>\n", *app->context_path ? app->context_path : "/", loc->prefix, ! loc->is_exact && ! loc->suffix ? "/*" : loc->suffix && loc->prefix[0] ? "/" : "", loc->suffix ? "*" : "", loc->suffix ? loc->suffix : "", loc->ignore ? " (ignore)" : ""); } } cse_printf(r, "</table></center>\n"); } cse_printf(r, "<hr>"); cse_printf(r, "<em>%s<em>", VERSION); cse_printf(r, "</body></html>\n");}intcse_handle_request(config_t *config, EXTENSION_CONTROL_BLOCK *r){ char host[1024]; char port_buf[80]; int port = 0; char url[BUF_LENGTH]; 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]) { DWORD now = GetTickCount() / 1000; 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, now)) return cse_error(config, r); } else return cse_error(config, r); stream_t s; return write_request(&s, r, config, host, port);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -