コード例 #1
0
ファイル: ClientImpl.cpp プロジェクト: 3Nigma/frayon
void ClientImpl::send(bool finished)
{
    if(_hstate == Idle || _hstate == OnRequestComplete)
    {
        // NOTE: might want to handle connect here in the future
        _hstate = OnRequest;
    }

    if(_hstate == OnRequest)
    {
        log_debug("begin sending request");
        _req.send(finished);

        log_debug("sent http request completed");
        _req.discard();
            
        if( _req.isFinished() )
        {
            ++_requestCount;
            _hstate = OnRequestComplete;
        }
        return;
    }

    log_error("sending HTTP request failed: " << _hstate);
    throw HttpError("HTTP message pending");
}
コード例 #2
0
ファイル: ClientImpl.cpp プロジェクト: 3Nigma/frayon
void ClientImpl::beginReceive()
{
    log_debug("beginReceive: " << _hstate);
    
    if(_hstate == Idle)
    {
        // NOTE: might want to handle connect here in the future
        _hstate = OnRequest;
    }
 
    if(_hstate == OnRequest)
    {
        log_debug("begin sending cached request");

        ///_req.finish();
        _hstate = OnRequestEnd;
    }

    if(_hstate == OnRequestEnd)
    {
        log_debug("flushing cached request");
        _req.beginSend(true);
        return;
    }

    if(_hstate == OnReply || _hstate == OnRequestComplete || _hstate == OnReplyComplete)
    {
        _hstate = OnReply;
        _reply.beginReceive();
        return;
    }

    throw HttpError("HTTP message pending");
}
コード例 #3
0
ファイル: ClientImpl.cpp プロジェクト: 3Nigma/frayon
MessageProgress ClientImpl::endSend()
{
    log_trace("endSend: " << _hstate);

    if(_hstate == OnRequest)
    {
        log_debug("sent http request");
        MessageProgress progress = _req.endSend();
        if( progress.finished() )
        {
            log_debug("sent http request completed");
            _req.discard();
            
            if( _req.isFinished() )
            {
                ++_requestCount;
                _hstate = OnRequestComplete;
                _reply.clear(); // TODO: find better place to clear reply !!!
            }
        }
            
        return progress;
    }

    throw HttpError("HTTP message pending");
    return MessageProgress();
}
コード例 #4
0
ファイル: ClientImpl.cpp プロジェクト: 3Nigma/frayon
std::istream& ClientImpl::receive()
{
    if(_hstate == Idle)
    {
        // NOTE: might want to handle connect here in the future
        _hstate = OnRequest;
    }
 
    if(_hstate == OnRequest)
    {
        log_debug("begin sending cached request");
        _hstate = OnRequestEnd;
    }

    if(_hstate == OnRequestEnd)
    {
        log_debug("flushing cached request");
        _req.send(true);

        log_debug("request completed");
        _hstate = OnReply;
        ++_requestCount;
        _req.discard();
    }

    if(_hstate == OnReply || _hstate == OnRequestComplete || _hstate == OnReplyComplete)
    {
        _hstate = OnReply;

        _reply.clear();
        _reply.receive();

        log_debug("reply completed");
        assert(0 != _requestCount);

        if( 0 == --_requestCount)
            _hstate = Idle;
        else
            _hstate = OnReplyComplete;

        if( ! _conn.isConnected() )
        {
            log_debug("connection closed");
            // connection will reconnect automatically
        }
        
        return _reply.body();
    }

    throw HttpError("HTTP message pending");
    return _reply.body();
}
コード例 #5
0
ファイル: ClientImpl.cpp プロジェクト: 3Nigma/frayon
MessageProgress ClientImpl::endReceive()
{
    log_debug("endReceive: " << _hstate);

    if(_hstate == OnRequestEnd)
    {
        log_debug("flushed cached request");
        MessageProgress progress = _req.endSend();
        if( progress.finished() )
        {
            log_debug("request completed");
            _req.discard();

            _hstate = OnReply;
            ++_requestCount;
            _reply.clear(); // TODO: find better place to clear reply !!!
        }
        
        return MessageProgress();
    }

    if(_hstate == OnReply)
    {   
        log_debug("receiving header");
        MessageProgress progress = _reply.endReceive();

        if( progress.finished() )
        {
            log_debug("reply completed");
            assert(0 != _requestCount);

            if( 0 == --_requestCount)
                _hstate = Idle;
            else
                _hstate = OnReplyComplete;

            if( ! _conn.isConnected() )
            {
                log_debug("connection closed");
                // connection will reconnect automatically
            }
        }

        return progress;
    }

    throw HttpError("HTTP message pending");
    return MessageProgress();
}
コード例 #6
0
ファイル: ClientImpl.cpp プロジェクト: 3Nigma/frayon
void ClientImpl::beginSend(bool finished)
{
    log_trace("beginSend: " << _hstate);
    
    if(_hstate == Idle || _hstate == OnRequestComplete)
    {
        // NOTE: might want to handle connect here in the future
        _hstate = OnRequest;
    }

    if(_hstate == OnRequest)
    {
        log_debug("begin sending http chunk");
        _req.beginSend(finished);
        return;
    }

    log_error("sending HTTP request failed: " << _hstate);
    throw HttpError("HTTP message pending");
}
コード例 #7
0
ファイル: Message.cpp プロジェクト: 3Nigma/frayon
void MessageHeader::add(const char* key, const char* value)
{ 
    log_debug("MessageHeader::add(\"" << key << "\", \"" << value << "\", " << replace << ')');

    if( ! *key)
        throw std::invalid_argument("header key is NULL");

    char* p = eptr();

    std::size_t lk = std::strlen(key);     // length of key
    std::size_t lv = std::strlen(value);   // length of value

    if (p - _rawdata + lk + lv + 2 > MaxHeaderSize)
        throw HttpError("message header too big");

    std::strcpy(p, key);   // copy key
    p += lk + 1;
    std::strcpy(p, value); // copy value
    p[lv + 1] = '\0';      // put new message end marker in place

    _endOffset = (p + lv + 1) - _rawdata;
}
コード例 #8
0
HttpRequestMessage::HttpRequestMessage(const std::string &buffer)
{
	HttpRequestPart current = HttpRequestPart_Start;
	std::stringstream stream(buffer);
	std::string line;

	// Basic HTTP parser.  This needs a LOT of refactoring.
	while (std::getline(stream, line, '\n')) {
		if (line.size() && line[line.size() - 1] == '\r') {
			line = line.substr(0, line.size() - 1);
		}

		switch (current) {
		case HttpRequestPart_Start:
			{
				auto remaining = line;

				// Get method
				auto split = remaining.find_first_of(" ");

				if (split == std::string::npos) {
					throw HttpError(Http::StatusCode_BadRequest, "Malformed begin request line, can't find method: '" + line + "'");
				}

				this->_method = remaining.substr(0, split);
				remaining = remaining.substr(split + 1);

				// Get path
				split = remaining.find_first_of(" ");

				if (split == std::string::npos) {
					throw HttpError(Http::StatusCode_BadRequest, "Malformed begin request line, can't find path: '" + line + "'");
				}

				this->_path = remaining.substr(0, split);
				remaining = remaining.substr(split + 1);

				// Get
				split = remaining.find_first_of("/");

				if (split == std::string::npos) {
					throw HttpError(Http::StatusCode_BadRequest, "Malformed begin request line, can't parse HTTP version: '" + line + "'");
				}
				
				auto http = remaining.substr(0, split);

				if (http != "HTTP") {
					throw HttpError(Http::StatusCode_BadRequest, "Malformed begin request line, missing HTTP from header: '" + line + "'");
				}

				auto version = remaining.substr(split + 1);

				this->_httpVersion = version;

				current = HttpRequestPart_Headers;
			}
			break;

		case HttpRequestPart_Headers:
			{
				bool whiteSpacesOnly = std::all_of(line.begin(), line.end(), isspace);

				if (whiteSpacesOnly) {
					current = HttpRequestPart_Body;
				}
				else {
					auto split = line.find_first_of(": ");

					if (split == std::string::npos) {
						throw HttpError(Http::StatusCode_BadRequest, "Malformed header line: '" + line + "'");
					}

					auto key = line.substr(0, split);
					auto value = line.substr(split + 2);
					this->_headers[key] = value;
				}
			}
			break;
		case HttpRequestPart_Body:
			{
				if (this->_body.size() > 0) {
					this->_body += "\n";
				}

				this->_body += line;
			}
			break;
		}
	}
}
コード例 #9
0
void CIVConnection::GetHTTPData(LPCTSTR szQuery, CString &rstr)
{
	TRACE (_T("HTTP Request: %s\n"), szQuery);

	DWORD dwServiceType = 0;
	CString strServer;
	CString strObject;		
	INTERNET_PORT nPort=0;
	bool    bFirst = false;
	
	HINTERNET hFile = NULL;

	bool bFailed = false;
	
	try
	{
		while(1)
		{
			if(!m_strHeader.GetLength())
				hFile = ::InternetOpenUrl (m_hSession, szQuery, NULL, 0,  INTERNET_FLAG_DONT_CACHE, 0 );
			else
				hFile = ::InternetOpenUrl (m_hSession, szQuery, (LPCSTR)m_strHeader, m_strHeader.GetLength(),  INTERNET_FLAG_DONT_CACHE, 0 );

			if (! hFile)
				AfxThrowInternetException(0);

			rstr.Empty();

			const int nSizeBuffer = 1024;
			BYTE pBuffer [nSizeBuffer];
			DWORD dwTotalRead = 0;

			while (true)
			{
				DWORD dwRead = 0;
				BOOL bResult = ::InternetReadFile (hFile, pBuffer, nSizeBuffer, &dwRead);
				if (! bResult)
					AfxThrowInternetException(0);
				
				if (dwRead ==0)
					break;

				DWORD dwOldTotal = dwTotalRead;
				dwTotalRead += dwRead;		

				LPTSTR szTarget = rstr.GetBuffer(dwTotalRead);
				szTarget += dwOldTotal;
	#ifndef _UNICODE				
				memcpy (szTarget, pBuffer, dwRead);
	#else
				MultiByteToWideChar (CP_ACP, 0, (LPCSTR) pBuffer, dwRead, szTarget, dwRead);			
	#endif //_UNICODE
				rstr.ReleaseBuffer(dwTotalRead);
			}

			if ( CheckErrorMessage(rstr) ) 
				bFailed = true;
			else
			{
				DWORD dwStatus = QueryInfoStatusCode(hFile);
				if(HTTP_STATUS_PROXY_AUTH_REQ == dwStatus && !bFirst && m_opts.m_iProxyAuth)
				{
					bFirst = true;

					CString strIn;
					CString strOut;
					unsigned nLen = 0;
					
					strIn.Format(_T("%s:%s"), (LPCTSTR)m_opts.m_strProxyLogin, (LPCTSTR)m_opts.m_strProxyPassword);
					encode64((LPCSTR)strIn, strIn.GetLength(), strOut.GetBufferSetLength(200), 190, &nLen);
					strOut.ReleaseBuffer();
					m_strHeader.Format(_T("Proxy-Authorization: Basic %s\r\n"),(LPCTSTR)strOut);
					InternetCloseHandle(hFile);
					continue;

				}
				if(!m_opts.m_iProxyAuth)
					m_strHeader = _T("");

				if ( HttpError (hFile, dwStatus) )
					bFailed = true;
			}
			break;
		}
	}
	catch (CInternetException * e )
	{
		bFailed = true;
		
		if ( e->m_dwError  != ERROR_INTERNET_OPERATION_CANCELLED  &&
			e->m_dwError  != ERROR_INVALID_HANDLE )
		{
			TCHAR szError [512] = _T("") ;
			e->GetErrorMessage(szError, sizeof (szError) / sizeof (TCHAR) );
			SetError (GetCommonIVError(szError));
		}
		else
			TRACE (_T("CIVConnection - canceled\n"));

		e->Delete();
	}

	TRACE (_T("End of HTTP request\n"));

	if (hFile)
		::InternetCloseHandle (hFile);

	if (bFailed)
		AfxThrowUserException();
}
コード例 #10
0
HttpErrorHandler::HttpError HttpErrorHandler::getError(const string& no) const{
	for(int i = 0;i < HTTP_ERRORS_KNOWN;i++)
		if(errInfo[i].no == no) return HttpError(i);
	throw Exception(string("Invalid err no: ") + no);
}
コード例 #11
0
ファイル: worker.cpp プロジェクト: deniskin82/tntnet
  void Worker::dispatch(HttpRequest& request, HttpReply& reply)
  {
    state = stateDispatch;
    const std::string& url = request.getUrl();

    if (!HttpRequest::checkUrl(url))
    {
      log_info("illegal url <" << url << '>');
      throw HttpError(HTTP_BAD_REQUEST, "illegal url");
    }

    request.setThreadContext(this);

    Dispatcher::PosType pos(application.getDispatcher(), request);
    while (true)
    {
      state = stateDispatch;

      // pos.getNext() throws NotFoundException at end
      Maptarget ci = pos.getNext();
      try
      {
        Component* comp = 0;
        try
        {
          if (ci.libname == application.getAppName())
          {
            // if the libname is the app name look first, if the component is
            // linked directly
            try
            {
              Compident cii = ci;
              cii.libname = std::string();
              comp = &comploader.fetchComp(cii, application.getDispatcher());
            }
            catch (const NotFoundException&)
            {
              // if the component is not found in the binary, fetchComp throws
              // NotFoundException and comp remains 0.
              // so we can ignore the exceptioni and just continue
            }
          }

          if (comp == 0)
            comp = &comploader.fetchComp(ci, application.getDispatcher());
        }
        catch (const NotFoundException& e)
        {
          log_debug("NotFoundException catched - url " << e.getUrl() << " try next mapping");
          continue;
        }

        request.setPathInfo(ci.hasPathInfo() ? ci.getPathInfo() : url);
        request.setArgs(ci.getArgs());

        std::string appname = application.getAppName().empty() ? ci.libname : application.getAppName();

        application.getScopemanager().preCall(request, appname);

        state = stateProcessingRequest;
        unsigned http_return;
        const char* http_msg;
        std::string msg;
        try
        {
          http_return = comp->topCall(request, reply, request.getQueryParams());
          http_msg = HttpReturn::httpMessage(http_return);
        }
        catch (const HttpReturn& e)
        {
          http_return = e.getReturnCode();
          msg = e.getMessage();
          http_msg = msg.c_str();
        }

        if (http_return != DECLINED)
        {
          if (reply.isDirectMode())
          {
            log_info("request " << request.getMethod_cstr() << ' ' << request.getQuery() << " ready, returncode " << http_return << ' ' << http_msg);
            state = stateFlush;
            reply.out().flush();
          }
          else
          {
            log_info("request " << request.getMethod_cstr() << ' ' << request.getQuery() << " ready, returncode " << http_return << ' ' << http_msg << " - ContentSize: " << reply.getContentSize());

            application.getScopemanager().postCall(request, reply, appname);

            state = stateSendReply;
            reply.sendReply(http_return, http_msg);
          }

          logRequest(request, reply, http_return);

          if (reply.out())
            log_debug("reply sent");
          else
          {
            reply.setKeepAliveCounter(0);
            log_warn("sending failed");
          }

          return;
        }
        else
          log_debug("component " << ci << " returned DECLINED");
      }
      catch (const LibraryNotFound& e)
      {
        log_warn("library " << e.getLibname() << " not found");
      }
    }

    throw NotFoundException(request.getUrl());
  }
コード例 #12
0
ファイル: worker.cpp プロジェクト: deniskin82/tntnet
  bool Worker::processRequest(HttpRequest& request, std::iostream& socket,
         unsigned keepAliveCount)
  {
    // log message
    log_info("request " << request.getMethod_cstr() << ' ' << request.getQuery()
      << " from client " << request.getPeerIp() << " user-Agent \"" << request.getUserAgent()
      << "\" user \"" << request.getUsername() << '"');

    // create reply-object
    HttpReply reply(socket);
    reply.setVersion(request.getMajorVersion(), request.getMinorVersion());
    if (request.isMethodHEAD())
      reply.setHeadRequest();

#ifdef ENABLE_LOCALE
    reply.setLocale(request.getLocale());
#endif

    if (request.keepAlive())
      reply.setKeepAliveCounter(keepAliveCount);

    if (TntConfig::it().enableCompression)
      reply.setAcceptEncoding(request.getEncoding());

    // process request
    try
    {
      try
      {
        dispatch(request, reply);

        if (!request.keepAlive() || !reply.keepAlive())
          keepAliveCount = 0;

        if (keepAliveCount > 0)
          log_debug("keep alive");
        else
        {
          log_debug("no keep alive request/reply="
              << request.keepAlive() << '/' << reply.keepAlive());
        }
      }
      catch (const HttpError& e)
      {
        throw;
      }
      catch (const std::exception& e)
      {
        throw HttpError(HTTP_INTERNAL_SERVER_ERROR, e.what());
      }
      catch (...)
      {
        log_error("unknown exception");
        throw HttpError(HTTP_INTERNAL_SERVER_ERROR, "unknown error");
      }
    }
    catch (const HttpError& e)
    {
      state = stateSendError;
      log_warn("http-Error: " << e.what());
      HttpReply errorReply(socket);
      errorReply.setVersion(request.getMajorVersion(), request.getMinorVersion());
      if (request.keepAlive())
        errorReply.setKeepAliveCounter(keepAliveCount);
      else
        keepAliveCount = 0;
      for (HttpMessage::header_type::const_iterator it = e.header_begin();
           it != e.header_end(); ++it)
        errorReply.setHeader(it->first, it->second);

      errorReply.out() << e.getBody() << '\n';
      errorReply.sendReply(e.getErrcode(), e.getErrmsg());
      logRequest(request, errorReply, e.getErrcode());
    }

    return keepAliveCount > 0;
  }