⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shorthand_isapi.cpp

📁 Shorthand是一个强大的脚本语言
💻 CPP
📖 第 1 页 / 共 3 页
字号:

		    // 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 + -