DWORD WINAPI WorkerFunction(IN LPVOID vECB)
{
	char szHeader[] = "Content-type: text/html\r\n\r\n";
	char szContent[] = "<html> <form method=get action=WorkerThread.dll><h1>Worker Thread Sample</h1><hr>"
										 "<input type=submit value=\"Send Request\"> </form></html>";

	/* Initialize local ECB pointer to void pointer passed to thread */

	EXTENSION_CONTROL_BLOCK *pECB = vECB;

	DWORD dwSize = strlen(szContent);

	/* Send outgoing header */

	SendHttpHeaders(pECB, "200 OK", szHeader, FALSE);

	/* Simulate extended processing for 5 seconds */

	Sleep(5000);

	/* Send content */

	pECB->WriteClient(pECB->ConnID, szContent, &dwSize, 0);

	/* Inform server that the request has been satisfied, and the connection may now be dropped */

	pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_DONE_WITH_SESSION, NULL, NULL, NULL);

	/* update global thread count */
	
	InterlockedDecrement(&g_dwThreadCount);

	return 0;
}
예제 #2
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%  C G I F i f o                                                              %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Method CGIFifo is the default output stream handler for CGI usage. It is
%  called by the stream subsystem whenever a buffer of data needs to be sent
%  to the output.It receives a pointer to the image as well as the buffer
%  of data and its length.
%
%  The format of the HttpUnescape method is:
%
%      int CGIFifo(const Image *image,const void *data,const size_t length)
%
%  A description of each parameter follows:
%
%    o image:  A pointer to the image being sent to the output stream.
%
%    o data: A pointer to the buffer of data to be sent.
%
%    o length: The length of the buffer of data to be sent.
%
*/
int CGIFifo(const Image *image,const void *data,const size_t length)
{
  EXTENSION_CONTROL_BLOCK *pECB;
  size_t tlen=length;
  pECB = (EXTENSION_CONTROL_BLOCK *)image->client_data;
  pECB->WriteClient( pECB->ConnID, (char *)data, &tlen, 0);
  return(tlen);
}
예제 #3
0
void ExtensionError(CControlBlock *pcb, const char *errmsg)
{
	char *windows_error = ::GetLastError() ?
	                          ::FormatSysError(::GetLastError()) : NULL;
	{ // temp scope to release python lock
	CEnterLeavePython celp;
	PySys_WriteStderr("Internal Extension Error: %s\n", errmsg);
	if (windows_error)
		PySys_WriteStderr("Last Windows error: %s\n", windows_error);
	if (PyErr_Occurred()) {
		PyErr_Print();
		PyErr_Clear();
	}
	} // end temp scope
	if (pcb) {
		char *htmlStream = HTMLErrorResp(errmsg);
	
		pcb->SetStatus(HSE_STATUS_ERROR);
		pcb->SetLogMessage(errmsg);
		HSE_SEND_HEADER_EX_INFO SendHeaderExInfo;
		SendHeaderExInfo.pszStatus = "200 OK";
		SendHeaderExInfo.cchStatus = strlen(SendHeaderExInfo.pszStatus);
		SendHeaderExInfo.pszHeader = "Content-type: text/html\r\n\r\n";
		SendHeaderExInfo.cchHeader = strlen(SendHeaderExInfo.pszHeader);
		SendHeaderExInfo.fKeepConn = FALSE;
		EXTENSION_CONTROL_BLOCK * ecb = pcb->GetECB();
		ecb->ServerSupportFunction(ecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &SendHeaderExInfo, NULL,NULL);
		pcb->WriteStream(htmlStream, strlen(htmlStream));
		if (windows_error) {
			static char *chunk = "<br>Last Windows error:";
			pcb->WriteStream(chunk, strlen(chunk));
			pcb->WriteStream(windows_error, strlen(windows_error));
		}
	}
	const char *inserts[] = {errmsg, windows_error ? windows_error : "n/a"};
	WriteEventLogMessage(EVENTLOG_ERROR_TYPE, E_PYISAPI_EXTENSION_FAILED,
			     2, inserts);
	if (windows_error)
		free(windows_error);
}
예제 #4
0
static int readContentData(HTTPRequest *req, void *dataBuffer, int dataSize, int mustFill)
{
    EXTENSION_CONTROL_BLOCK *p = (EXTENSION_CONTROL_BLOCK *)req->api_handle;
    DWORD len_remaining = dataSize;
    DWORD total_len_read = 0;
    char *buffer = (char *)dataBuffer;
    MS_BOOL readStatus;
    unsigned int lenZeroCounter = 0;

    DWORD len;
    if(p->cbAvailable > req->total_len_read)
    {
        len = p->cbAvailable - req->total_len_read;
        if(len > dataSize) len = dataSize;
        memcpy(buffer, p->lpbData + req->total_len_read, len);
        
        total_len_read += len;
        len_remaining -= len;
    }

    /*
     * IIS has a weird (or is it convenient?) data queuing mechanism...
     */
    while(len_remaining > 0 &&
          (mustFill || total_len_read == 0))
    {
        len = len_remaining;
        readStatus = p->ReadClient (p->ConnID,buffer + total_len_read, &len);
        if(readStatus == TRUE)
        {
           // 2009/04/29: avoid endless loops, because the ReadClient function
           //             will return TRUE but with zero bytes read if the
           //             socket on which the server is listening to the client
           //             is closed!!!
           lenZeroCounter =
              ((len == 0)? (lenZeroCounter + 1) : 0);
           if(lenZeroCounter > MAGIC_LEN_ZERO_LIMIT)
           {
               readStatus = FALSE;
           }
        }

        if(readStatus != TRUE)
        {
           if(lenZeroCounter > MAGIC_LEN_ZERO_LIMIT)
           {
              WOLog(WO_ERR,"ReadClient failed (client socket closed?).");
           }
           else
           {
              WOLog(WO_ERR,"ReadClient failed");
           }
           die(p, INV_FORM_DATA, HTTP_BAD_REQUEST);
           return -1;
        }

        total_len_read += len;
        len_remaining -= len;
    }

    // still required? - BEGIN
    if (req_HeaderForKey(req, CONTENT_LENGTH) == NULL) {
       char *length;
       length = (char *)WOMALLOC(32);
       if (length)
       {
          sprintf(length,"%lu",req->content_length);
          req_addHeader(req, CONTENT_LENGTH, length, STR_FREEVALUE);
       }
       if (p->lpszContentType != NULL)
          req_addHeader(req, CONTENT_TYPE, p->lpszContentType, 0);
    }
    // still required? - END

    req->total_len_read += total_len_read;
    return total_len_read;
}