📄 shorthand_isapi.cpp
字号:
// Free pages below current page
if (!VirtualFree(mi.AllocationBase, (LPBYTE)lpPage - (LPBYTE) mi.AllocationBase, MEM_DECOMMIT)) {
_endthread();
}
// Restore the guard page
if (!VirtualProtect(lpPage, si.dwPageSize, PAGE_GUARD | PAGE_READWRITE, &dwOldProtect)) {
_endthread();
}
CG(unclean_shutdown)=1;
_snprintf(buf, sizeof(buf)-1,"PHP has encountered a Stack overflow");
php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
} else if (_exception_code()==EXCEPTION_ACCESS_VIOLATION) {
_snprintf(buf, sizeof(buf)-1,"PHP has encountered an Access Violation at %p", e->ExceptionRecord->ExceptionAddress);
php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
my_endthread();
} else {
_snprintf(buf, sizeof(buf)-1,"PHP has encountered an Unhandled Exception Code %d at %p", e->ExceptionRecord->ExceptionCode , e->ExceptionRecord->ExceptionAddress);
php_isapi_report_exception(buf, strlen(buf) TSRMLS_CC);
my_endthread();
}
*/
}
__try
{
//php_request_shutdown(NULL);
} __except(EXCEPTION_EXECUTE_HANDLER) {
//my_endthread();
}
return HSE_STATUS_SUCCESS;
}
extern "C"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
#ifdef _DEBUG
//trace_level = 10;
//TRACE((3, "ISAPI: DllMain(DLL_PROCESS_ATTACH) started\n"));
#endif
/*TODO:
sapi_startup(&isapi_sapi_module);
if (isapi_sapi_module.startup) {
isapi_sapi_module.startup(&sapi_module);
}*/
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
//TODO: ts_free_thread();
break;
case DLL_PROCESS_DETACH:
/*TODO:
if (isapi_sapi_module.shutdown)
{
isapi_sapi_module.shutdown(&sapi_module);
}
tsrm_shutdown();
*/
break;
}
return TRUE;
}
/**
* main module interpretation function
*/
int isapi_shorthand_main(LPEXTENSION_CONTROL_BLOCK ecb, int display_source_mode)
{
#ifdef _DEBUG
extern int trace_level;
trace_level = 20;
#endif
int rc = 0;
ISAPIHttpStream stream(ecb);
ShhModule module(ecb->lpszPathTranslated);
try
{
char szValue[1024];
DWORD dwValueSize;
char *szName;
char ** variables = (char**) isapi_server_variable_names;
int i=0;
while((szName = variables[i++]) != NULL)
{
dwValueSize = sizeof(szValue);
if (ecb->GetServerVariable(ecb->ConnID, szName, szValue, &dwValueSize))
{
SetEnvironmentVariable(szName, szValue);
}
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
mstream scratch;
void* buffer = scratch.provide_window(dwValueSize+1);
if (ecb->GetServerVariable(ecb->ConnID, szName, buffer, &dwValueSize))
{
SetEnvironmentVariable(szName, (char*)buffer);
}
}
}
//ap_add_cgi_vars(r);
//ap_parse_uri_components(r->pool, r->unparsed_uri, &r->parsed_uri);
//ap_add_common_vars(r);
/*
char** env = ap_create_environment(r->pool, r->subprocess_env);
char* e = *env;
while(e != NULL && *e != '\0')
{
TRACE((2, "putenv: %s...\n", e));
safe_putenv(strdup(e));
e = *++env;
}
*/
putenf("SHORTHAND_VERSION", "%s", shorthand_version);
mstream input; input.load_from_file(ecb->lpszPathTranslated);
// execute the script
module.execute_script(input.data(), &stream);
}
catch(ShhException* ex)
{
string msg;
msg.printf("\n\n<br><br><b>Error %s:</b> %s\r\n", ex->href(), ex->message());
TRACE((2, "execution exception %04d: %s\n", ex->code(), ex->message()));
fprintf(stderr, "mod_shorthand: error %04d: %s\n", ex->code(), ex->message());
stream.http_write_chunk(msg.cstr(), msg.length());
}
stream.http_finalize();
return stream.code();
}
int ISAPIHttpStream::http_write_chunk(const void* chunk_data, unsigned int chunk_length)
{
if (!m_headers_sent) http_send_headers();
int count = 0;
if (chunk_length > 0)
{
count += isapi_write_client(m_ecb, (const char*) chunk_data, chunk_length);
}
return count;
}
/**
* Reads a piece of data sent by client in PUT or POST request.
*/
int ISAPIHttpStream::http_read(void* buffer, int buffer_size)
{
if (!m_did_client_block)
{
m_did_client_block = true;
}
if (m_ecb->cbAvailable <= 0) { return 0; }
if (buffer_size < 0) buffer_size = 0;
DWORD dwSize = 0;
DWORD dwBufferSize = (DWORD) buffer_size;
BOOL bReadStatus;
TRACE((1, "http_read(): cbTotalBytes=%d, cbAvailable=%d; m_input_offset=%d\n",
m_ecb->cbTotalBytes, m_ecb->cbAvailable, m_input_offset));
if (m_input_offset >= m_ecb->cbTotalBytes) return 0;
else if (m_input_offset < m_ecb->cbAvailable)
{
dwSize = m_ecb->cbAvailable - m_input_offset;
bReadStatus = TRUE;
if (dwSize > dwBufferSize) dwSize = dwBufferSize;
memcpy(buffer, ((char*)m_ecb->lpbData)+m_input_offset, dwSize);
}
else if (m_ecb->cbAvailable < m_ecb->cbTotalBytes)
{
dwSize = buffer_size;
if (dwSize > m_ecb->cbAvailable) dwSize = m_ecb->cbAvailable;
bReadStatus = m_ecb->ReadClient(m_ecb->ConnID, buffer, &dwSize);
#ifdef _DEBUG
if (bReadStatus)
TRACE((1, "http_read(): ReadClient() finished (got %d bytes)\n", dwSize));
else
TRACE((1, "http_read(): ReadClient() failed (%d/0x%08x)\n", GetLastError(), GetLastError()));
#endif
}
m_input_offset += dwSize;
if (!bReadStatus || dwSize == 0)
{
m_have_input = false;
return 0;
}
m_have_input = true;
return dwSize;
}
const char* ISAPIHttpStream::http_get_cookie(const char* name)
{
if (!m_cookies_grabbed) grab_cookies();
string** value = m_in_cookies.get(name);
if (value == NULL || *value == NULL)
return NULL;
else
return (*value)->cstr();
}
int ISAPIHttpStream::http_set_cookie(const CHttpCookie* cookie)
{
m_out_cookies.add(cookie->clone());
return 0;
}
void ISAPIHttpStream::grab_cookies()
{
string tmp;
const char* cookies = safe_getenv("HTTP_COOKIE", tmp);
//cookies = "cookie1=value1; c3=; cookie2=This is the value (%3b) of cookie called \"Cookie2\"";
if (cookies == NULL) cookies = "";
int length = strlen(cookies);
TRACE((8, "cookies: %s\n", cookies));
RX cookies_rx(" *([^=]+) *= *([^;]*);?");
int off = 0;
while((off = cookies_rx.search(cookies, length, off, false)) != -1)
{
string name, value;
cookies_rx.submatch(cookies, 1, name);
cookies_rx.submatch(cookies, 2, value);
TRACE((8, "in-cookie: name=%s value=%s\n", name.cstr(), value.cstr()));
string clean_value;
value.urldecode(clean_value);
m_in_cookies.put(name, clean_value.clone());
}
//http_add_header("X-Cookies", cookies ? cookies : "");
m_cookies_grabbed = true;
}
int ISAPIHttpStream::http_add_header(const char* name, const char* value)
{
//TODO: ap_table_set(m_req->headers_out, name, value);
if (stricmp(name, "Location") == 0) m_response_code = 302;
m_out_headers.put(name, new string(value));
return 0;
}
// overrides HTTP response code (with optional status line message)
// most servers will allow to change code, but few allow to change message
void ISAPIHttpStream::http_set_response_code(int code, const char* msg)
{
m_response_code = code;
m_response_message = msg;
m_ecb->dwHttpStatusCode = code;
}
int ISAPIHttpStream::http_finalize()
{
if (!m_headers_sent)
{
http_send_headers();
}
return 0;
}
int ISAPIHttpStream::http_send_headers()
{
int i,n;
if (m_headers_sent) return 0;
HSE_SEND_HEADER_EX_INFO xSendHeader;
mstream headers;
if (!m_out_headers.key_exists("Content-Type"))
{
m_out_headers.put("Content-Type", new string("text/html"));
}
for(i=0,n=m_out_headers.size(); i<n; i++)
{
string* value = NULL;
const char* name = m_out_headers.key_at(i, value);
headers.puts(name);
headers.puts(": ");
headers.puts(value->cstr());
headers.puts("\n");
}
for(i=0,n=m_out_cookies.size(); i<n; i++)
{
CHttpCookie* cookie = m_out_cookies.get(i);
if (cookie == NULL || cookie->is_deleted()) continue;
string line; cookie->create_response(line, true);
// TODO!!!
//ap_table_add(m_req->headers_out, "Set-Cookie", line);
headers.puts("Set-Cookie: ");
headers.puts(line);
headers.puts("\n");
}
headers.puts("\n");
string status;
status.printf("%d %s", m_response_code, m_response_message.cstr());
TRACE((3, "status: %s\n", m_response_message.cstr()));
xSendHeader.pszStatus = status.cstr();
xSendHeader.cchStatus = status.length();
xSendHeader.pszHeader = headers.data();
xSendHeader.cchHeader = headers.size();
xSendHeader.fKeepConn = FALSE;
//ap_send_http_header(m_req);
m_ecb->lpszContentType = (char*) m_content_type.cstr();
BOOL bStatus = m_ecb->ServerSupportFunction(m_ecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX,
&xSendHeader, NULL, NULL);
m_headers_sent = true;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -