Ejemplo n.º 1
0
	BOOL HttpProtocol::GetContent(std::map<std::string , std::string> & mapContent)
	{
		INT32 nLength = GetContentLength();
		std::string strContent = GetContent();
		while (strContent.size() > 0)
		{
			size_t pos = strContent.find('=');
			size_t posNext = strContent.find('&');
			if (std::string::npos != pos)
			{
				std::string strKey = strContent.substr(0, pos);
				std::string strVal = "";
				if (posNext != std::string::npos)
				{
					strVal = strContent.substr(pos + 1, posNext - pos - 1);
					strContent = strContent.substr(posNext + 1, nLength - posNext - 1);
				}
				else
				{
					strContent = "";
				}
				mapContent.insert(std::make_pair(strKey , strVal));
			}
			else
			{
				strContent = "";
			}
		}

		return TRUE;
	}
Ejemplo n.º 2
0
   shared_ptr<MimeBody> 
      MimeBody::LoadEncapsulatedMessage() const
   {
      // try to generate a file name using the message subject.
      shared_ptr<MimeBody> pEncapsulatedMessage = shared_ptr<MimeBody>(new MimeBody);

      int iLength = GetContentLength();
      char *pData = new char[iLength+1];
      strncpy(pData, (const char*) GetContent(), iLength);
      int index = 0;
      pEncapsulatedMessage->Load(pData, iLength, index);
      delete [] pData;

      return pEncapsulatedMessage;
   }
Ejemplo n.º 3
0
static void
LoadCallback(void *user_data, int32_t result)
{
  int32_t len;
  responseInfo = loader_->GetResponseInfo(loader);
  loader_status = responseInfo_->GetProperty(responseInfo, PP_URLRESPONSEPROPERTY_HEADERS);
  len = GetContentLength(loader_status);
  sprintf(buffer, "len: %d\n", (int)len);
  Log(buffer);
  if (len > 0) {
    file = malloc(len);
    Log (file ? "file buffer allocated\n" : "allocation failed\n");
    loader_->ReadResponseBody(loader, file, len, ReadCompletionCallback);
  }
}
Ejemplo n.º 4
0
QuviMedia::QuviMedia(std::wstring&& url)
	: QuviMediaInfo(std::move(url))
	, m_curlsh(curl_share_init())
{
	assert(m_curlsh); // TODO: throw exception
	curl_share_setopt(m_curlsh, CURLSHOPT_LOCKFUNC, CurlShareLockFunction);
	curl_share_setopt(m_curlsh, CURLSHOPT_UNLOCKFUNC, CurlShareUnlockFunction);
	curl_share_setopt(m_curlsh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
	curl_share_setopt(m_curlsh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
	curl_share_setopt(m_curlsh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
	curl_share_setopt(m_curlsh, CURLSHOPT_USERDATA, &m_curlshLock);

	curl_easy_setopt(m_curl, CURLOPT_SHARE, m_curlsh);
	// TODO: ensure that cookies are properly inherited

	if (GetContentType() == "video/vnd.mpeg.dash.mpd") {
		std::string murl = GetMultibyteUrl();
		if (murl.empty())
			throw 1; // TODO: replace with some sensible exception
		std::unique_ptr<dash::IDASHManager> manager(CreateDashManager());
		if (!manager)
			throw 1; // TODO: replace with some sensible exception
		std::unique_ptr<dash::mpd::IMPD> mpd(manager->Open(&murl[0]));
		if (!mpd)
			throw 1; // TODO: replace with some sensible exception

		const auto& period = mpd->GetPeriods().front();

		for (const auto& adaptationSet : period->GetAdaptationSets()) {
			const auto& representation = adaptationSet->GetRepresentation().back();

			enum class DashRepresentationType {
				Base,
				Template,
				List,
			};

			auto determineType = [](const dash::mpd::IPeriod* period,
				const dash::mpd::IAdaptationSet* adaptationSet,
				const dash::mpd::IRepresentation* representation) -> DashRepresentationType {
				assert(representation && adaptationSet && period);
				if (representation->GetSegmentList())
					return DashRepresentationType::List;
				if (representation->GetSegmentTemplate())
					return DashRepresentationType::Template;
				if (representation->GetSegmentBase() || !representation->GetBaseURLs().empty())
					return DashRepresentationType::Base;

				if (adaptationSet->GetSegmentList())
					return DashRepresentationType::List;
				if (adaptationSet->GetSegmentTemplate())
					return DashRepresentationType::Template;
				if (adaptationSet->GetSegmentBase())
					return DashRepresentationType::Base;

				if (period->GetSegmentList())
					return DashRepresentationType::List;
				if (period->GetSegmentTemplate())
					return DashRepresentationType::Template;
				if (period->GetSegmentBase())
					return DashRepresentationType::Base;

				throw 1; // TODO: replace with some sensible exception
			};

			const DashRepresentationType type = determineType(period, adaptationSet, representation);

			if (type != DashRepresentationType::Base) // TODO: support other stream types
				throw 1; // TODO: replace with some sensible exception

			// TODO: support compound urls
			std::unique_ptr<dash::network::IChunk> chunk(representation->GetBaseURLs()[0]->ToMediaSegment({}));
			if (!chunk)
				throw 1; // TODO: replace with some sensible exception

			auto& uri = chunk->AbsoluteURI();
			if (uri.empty())
				throw 1; // TODO: replace with some sensible exception

			curl_easy_setopt(m_curl, CURLOPT_URL, &uri[0]);
			curl_easy_setopt(m_curl, CURLOPT_NOBODY, 1L);

			CURLcode cc = curl_easy_perform(m_curl);
			if (cc != CURLE_OK)
				throw 1; // TODO: replace with some sensible exception

			// TODO: use return codes
			long code = 0, proxycode = 0;
			curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &code);
			curl_easy_getinfo(m_curl, CURLINFO_HTTP_CONNECTCODE, &proxycode);

			double size = 0;
			curl_easy_getinfo(m_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size);

			curl_easy_setopt(m_curl, CURLOPT_HTTPGET, 1L);
			m_backends.emplace_back(std::make_unique<QuviSimpleStreamBackend>((uint64_t)size, m_curl, m_curlsh));
		}
	} else {
		assert(m_backends.empty());
		m_backends.emplace_back(std::make_unique<QuviSimpleStreamBackend>(GetContentLength(), m_curl, m_curlsh));
	}
}
Ejemplo n.º 5
0
BUF *HttpRequestEx2(URL_DATA *data, INTERNET_SETTING *setting,
				   UINT timeout_connect, UINT timeout_comm,
				   UINT *error_code, bool check_ssl_trust, char *post_data,
				   WPC_RECV_CALLBACK *recv_callback, void *recv_callback_param, void *sha1_cert_hash,
				   bool *cancel, UINT max_recv_size, char *header_name, char *header_value)
{
	WPC_CONNECT con;
	SOCK *s;
	HTTP_HEADER *h;
	bool use_http_proxy = false;
	char target[MAX_SIZE * 4];
	char *send_str;
	BUF *send_buf;
	BUF *recv_buf;
	UINT http_error_code;
	char len_str[100];
	UINT content_len;
	void *socket_buffer;
	UINT socket_buffer_size = WPC_RECV_BUF_SIZE;
	UINT num_continue = 0;
	INTERNET_SETTING wt_setting;
	// Validate arguments
	if (data == NULL)
	{
		return NULL;
	}
	if (setting == NULL)
	{
		Zero(&wt_setting, sizeof(wt_setting));
		setting = &wt_setting;
	}
	if (error_code == NULL)
	{
		static UINT ret = 0;
		error_code = &ret;
	}
	if (timeout_comm == 0)
	{
		timeout_comm = WPC_TIMEOUT;
	}

	// Connection
	Zero(&con, sizeof(con));
	StrCpy(con.HostName, sizeof(con.HostName), data->HostName);
	con.Port = data->Port;
	con.ProxyType = setting->ProxyType;
	StrCpy(con.ProxyHostName, sizeof(con.ProxyHostName), setting->ProxyHostName);
	con.ProxyPort = setting->ProxyPort;
	StrCpy(con.ProxyUsername, sizeof(con.ProxyUsername), setting->ProxyUsername);
	StrCpy(con.ProxyPassword, sizeof(con.ProxyPassword), setting->ProxyPassword);

	if (setting->ProxyType != PROXY_HTTP || data->Secure)
	{
		use_http_proxy = false;
		StrCpy(target, sizeof(target), data->Target);
	}
	else
	{
		use_http_proxy = true;
		CreateUrl(target, sizeof(target), data);
	}

	if (use_http_proxy == false)
	{
		// If the connection is not via HTTP Proxy, or is a SSL connection even via HTTP Proxy
		s = WpcSockConnectEx(&con, error_code, timeout_connect, cancel);
	}
	else
	{
		// If the connection is not SSL via HTTP Proxy
		s = TcpConnectEx3(con.ProxyHostName, con.ProxyPort, timeout_connect, cancel, NULL, true, NULL, false, false, NULL);
		if (s == NULL)
		{
			*error_code = ERR_PROXY_CONNECT_FAILED;
		}
	}

	if (s == NULL)
	{
		return NULL;
	}

	if (data->Secure)
	{
		// Start the SSL communication
		if (StartSSLEx(s, NULL, NULL, true, 0, NULL) == false)
		{
			// SSL connection failed
			*error_code = ERR_PROTOCOL_ERROR;
			Disconnect(s);
			ReleaseSock(s);
			return NULL;
		}

		if (sha1_cert_hash != NULL)
		{
			UCHAR hash[SHA1_SIZE];
			Zero(hash, sizeof(hash));
			GetXDigest(s->RemoteX, hash, true);

			if (Cmp(hash, sha1_cert_hash, SHA1_SIZE) != 0)
			{
				// Destination certificate hash mismatch
				*error_code = ERR_CERT_NOT_TRUSTED;
				Disconnect(s);
				ReleaseSock(s);
				return NULL;
			}
		}
	}

	// Timeout setting
	SetTimeout(s, timeout_comm);

	// Generate a request
	h = NewHttpHeader(data->Method, target, use_http_proxy ? "HTTP/1.0" : "HTTP/1.1");
	AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
	AddHttpValue(h, NewHttpValue("Accept-Language", "ja"));
	AddHttpValue(h, NewHttpValue("User-Agent", WPC_USER_AGENT));
	AddHttpValue(h, NewHttpValue("Pragma", "no-cache"));
	AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
	AddHttpValue(h, NewHttpValue("Host", data->HeaderHostName));

	if (IsEmptyStr(header_name) == false && IsEmptyStr(header_value) == false)
	{
		AddHttpValue(h, NewHttpValue(header_name, header_value));
	}

	if (IsEmptyStr(data->Referer) == false)
	{
		AddHttpValue(h, NewHttpValue("Referer", data->Referer));
	}

	if (StrCmpi(data->Method, WPC_HTTP_POST_NAME) == 0)
	{
		ToStr(len_str, StrLen(post_data));
		AddHttpValue(h, NewHttpValue("Content-Type", "application/x-www-form-urlencoded"));
		AddHttpValue(h, NewHttpValue("Content-Length", len_str));
	}

	if (IsEmptyStr(data->AdditionalHeaderName) == false && IsEmptyStr(data->AdditionalHeaderValue) == false)
	{
		AddHttpValue(h, NewHttpValue(data->AdditionalHeaderName, data->AdditionalHeaderValue));
	}

	if (use_http_proxy)
	{
		AddHttpValue(h, NewHttpValue("Proxy-Connection", "Keep-Alive"));

		if (IsEmptyStr(setting->ProxyUsername) == false || IsEmptyStr(setting->ProxyPassword) == false)
		{
			char auth_tmp_str[MAX_SIZE], auth_b64_str[MAX_SIZE * 2];
			char basic_str[MAX_SIZE * 2];

			// Generate the authentication string
			Format(auth_tmp_str, sizeof(auth_tmp_str), "%s:%s",
				setting->ProxyUsername, setting->ProxyPassword);

			// Base64 encode
			Zero(auth_b64_str, sizeof(auth_b64_str));
			Encode64(auth_b64_str, auth_tmp_str);
			Format(basic_str, sizeof(basic_str), "Basic %s", auth_b64_str);

			AddHttpValue(h, NewHttpValue("Proxy-Authorization", basic_str));
		}
	}

	send_str = HttpHeaderToStr(h);
	FreeHttpHeader(h);

	send_buf = NewBuf();
	WriteBuf(send_buf, send_str, StrLen(send_str));
	Free(send_str);

	// Append to the sending data in the case of POST
	if (StrCmpi(data->Method, WPC_HTTP_POST_NAME) == 0)
	{
		WriteBuf(send_buf, post_data, StrLen(post_data));
	}

	// Send
	if (SendAll(s, send_buf->Buf, send_buf->Size, s->SecureMode) == false)
	{
		Disconnect(s);
		ReleaseSock(s);
		FreeBuf(send_buf);

		*error_code = ERR_DISCONNECTED;

		return NULL;
	}

	FreeBuf(send_buf);

CONT:
	// Receive
	h = RecvHttpHeader(s);
	if (h == NULL)
	{
		Disconnect(s);
		ReleaseSock(s);

		*error_code = ERR_DISCONNECTED;

		return NULL;
	}

	http_error_code = 0;
	if (StrLen(h->Method) == 8)
	{
		if (Cmp(h->Method, "HTTP/1.", 7) == 0)
		{
			http_error_code = ToInt(h->Target);
		}
	}

	*error_code = ERR_NO_ERROR;

	switch (http_error_code)
	{
	case 401:
	case 407:
		// Proxy authentication error
		*error_code = ERR_PROXY_AUTH_FAILED;
		break;

	case 404:
		// 404 File Not Found
		*error_code = ERR_OBJECT_NOT_FOUND;
		break;

	case 100:
		// Continue
		num_continue++;
		if (num_continue >= 10)
		{
			goto DEF;
		}
		FreeHttpHeader(h);
		goto CONT;

	case 200:
		// Success
		break;

	default:
		// Protocol error
DEF:
		*error_code = ERR_PROTOCOL_ERROR;
		break;
	}

	if (*error_code != ERR_NO_ERROR)
	{
		// An error has occured
		Disconnect(s);
		ReleaseSock(s);
		FreeHttpHeader(h);
		return NULL;
	}

	// Get the length of the content
	content_len = GetContentLength(h);
	if (max_recv_size != 0)
	{
		content_len = MIN(content_len, max_recv_size);
	}

	FreeHttpHeader(h);

	socket_buffer = Malloc(socket_buffer_size);

	// Receive the content
	recv_buf = NewBuf();

	while (true)
	{
		UINT recvsize = MIN(socket_buffer_size, content_len - recv_buf->Size);
		UINT size;

		if (recv_callback != NULL)
		{
			if (recv_callback(recv_callback_param,
				content_len, recv_buf->Size, recv_buf) == false)
			{
				// Cancel the reception
				*error_code = ERR_USER_CANCEL;
				goto RECV_CANCEL;
			}
		}

		if (recvsize == 0)
		{
			break;
		}

		size = Recv(s, socket_buffer, recvsize, s->SecureMode);
		if (size == 0)
		{
			// Disconnected
			*error_code = ERR_DISCONNECTED;

RECV_CANCEL:
			FreeBuf(recv_buf);
			Free(socket_buffer);
			Disconnect(s);
			ReleaseSock(s);

			return NULL;
		}

		WriteBuf(recv_buf, socket_buffer, size);
	}

	SeekBuf(recv_buf, 0, 0);
	Free(socket_buffer);

	Disconnect(s);
	ReleaseSock(s);

	// Transmission
	return recv_buf;
}
PRInt32 nsMailboxProtocol::ReadMessageResponse(nsIInputStream * inputStream, PRUint32 sourceOffset, PRUint32 length)
{
  char *line = nsnull;
  PRUint32 status = 0;
  nsresult rv = NS_OK;
  mCurrentProgress += length;
  
  // if we are doing a move or a copy, forward the data onto the copy handler...
  // if we want to display the message then parse the incoming data...
  
  if (m_channelListener)
  {
    // just forward the data we read in to the listener...
    rv = m_channelListener->OnDataAvailable(this, m_channelContext, inputStream, sourceOffset, length);
  }
  else
  {
    PRBool pauseForMoreData = PR_FALSE;
    PRBool canonicalLineEnding = PR_FALSE;
    nsCOMPtr<nsIMsgMessageUrl> msgurl = do_QueryInterface(m_runningUrl);
    
    if (msgurl)
      msgurl->GetCanonicalLineEnding(&canonicalLineEnding);
    do
    {
      char *saveLine;
      saveLine = line = m_lineStreamBuffer->ReadNextLine(inputStream, status, pauseForMoreData);
      
      if (!line || (line[0] == '.' && line[1] == 0))
      {
        // we reached the end of the message!
        ClearFlag(MAILBOX_PAUSE_FOR_READ);
      } // otherwise process the line
      else
      {
        if (line[0] == '.')
          line++; // skip over the '.'
        
        /* When we're sending this line to a converter (ie,
        it's a message/rfc822) use the local line termination
        convention, not CRLF.  This makes text articles get
        saved with the local line terminators.  Since SMTP
        and NNTP mandate the use of CRLF, it is expected that
        the local system will convert that to the local line
        terminator as it is read.
        */
        // mscott - the firstline hack is aimed at making sure we don't write
        // out the dummy header when we are trying to display the message.
        // The dummy header is the From line with the date tag on it.
        if (m_msgFileOutputStream && TestFlag(MAILBOX_MSG_PARSE_FIRST_LINE))
        {
          PRUint32 count = 0;
          if (line)
            rv = m_msgFileOutputStream->Write(line, PL_strlen(line),
            &count);
          if (NS_FAILED(rv)) break;
          
          if (canonicalLineEnding)
            rv = m_msgFileOutputStream->Write(CRLF, 2, &count);
          else
            rv = m_msgFileOutputStream->Write(MSG_LINEBREAK,
            MSG_LINEBREAK_LEN, &count);
          
          if (NS_FAILED(rv)) break;
        }
        else
          SetFlag(MAILBOX_MSG_PARSE_FIRST_LINE);
      } 
      PR_Free(saveLine);
    }
    while (line && !pauseForMoreData);
  }
  
  SetFlag(MAILBOX_PAUSE_FOR_READ); // wait for more data to become available...
  if (mProgressEventSink)
  {
    PRInt32 contentLength = 0;
    GetContentLength(&contentLength);
    // XXX 64-bit
    mProgressEventSink->OnProgress(this, m_channelContext,
                                   nsUint64(mCurrentProgress),
                                   nsUint64(contentLength));
  }
  
  if (NS_FAILED(rv)) return -1;
  
  return 0;
}
Ejemplo n.º 7
0
////////////////////////////////////////////////////////////////////////////////////////////
/// Extract the data fields from the header buffer and populate the member data fields.
/// \param pReceiveBuffer The input data
/// \return True if suucess, False if fail.
////////////////////////////////////////////////////////////////////////////////////////////
bool HTTPRequestHeader::ExtractHeaderData(char* pReceiveBuffer)
{
    char* pos = NULL;
    char* context = NULL;

    ////////////////////////////////////////////////////////////////////////
    // tokenize the buffer for method
    pos = strtok_s(pReceiveBuffer, " ", &context);

    if (pos == NULL)
    {
        Log(logERROR, "Failed to tokenize HTTPHeader for method\n");
        return false;
    }

    // get the method (GET or POST)
    size_t methodLen = strlen(pos);

    if (methodLen > SMALL_BUFFER_SIZE)
    {
        Log(logERROR, "HTTP method is larger than buffer: %u > %u\n", methodLen, SMALL_BUFFER_SIZE);
        return false;
    }

    strncpy_s(m_httpHeaderData.method, SMALL_BUFFER_SIZE, pos, SMALL_BUFFER_SIZE);

    ////////////////////////////////////////////////////////////////////////
    //tokenize the buffer for url
    pos = strtok_s(NULL, " ", &context);

    if (pos == NULL)
    {
        Log(logERROR, "Failed to tokenize HTTPHeader for url\n");
        return false;
    }

    // get the url
    size_t urlLen = strlen(pos);

    if (urlLen > COMM_MAX_URL_SIZE)
    {
        Log(logERROR, "HTTP url is larger than buffer: %u > %u\n", urlLen, COMM_MAX_URL_SIZE);
        return false;
    }

    strncpy_s(m_httpHeaderData.url, COMM_MAX_URL_SIZE, pos, COMM_MAX_URL_SIZE);

    ////////////////////////////////////////////////////////////////////////
    // tokenize the buffer for version
    pos = strtok_s(NULL, "\r", &context);

    if (pos == NULL)
    {
        Log(logERROR, "Failed to tokenize HTTPHeader for version\n");
        return false;
    }

    // get the version
    size_t verLen = strlen(pos);

    if (verLen > SMALL_BUFFER_SIZE)
    {
        Log(logERROR, "HTTP version string is larger than buffer: %u > %u\n", verLen, SMALL_BUFFER_SIZE);
        return false;
    }

    strncpy_s(m_httpHeaderData.httpversion, SMALL_BUFFER_SIZE, pos, SMALL_BUFFER_SIZE);

    ////////////////////////////////////////////////////////////////////////
    // tokenize the buffer for content
    pos = strtok_s(NULL, "\r", &context);

    if (pos == NULL)
    {
        Log(logERROR, "Failed to tokenize HTTPHeader for Content-Type\n");
        return false;
    }

    // Currently we do nothing with content type.

    ////////////////////////////////////////////////////////////////////////
    // tokenize the buffer for Host
    pos = strtok_s(NULL, "\r", &context);

    if (pos == NULL)
    {
        Log(logERROR, "Failed to tokenize HTTPHeader for Host\n");
        return false;
    }

    // Currently we do nothing with Host.

    ////////////////////////////////////////////////////////////////////////
    // Check to see if POST method is being used to send anay data.
    if (strcmp(m_httpHeaderData.method, "POST") == 0)
    {
        // If so, record how much data is being sent.
        m_httpHeaderData.nPostDataSize = GetContentLength(context);
    }

    return true;
}
Ejemplo n.º 8
0
//=============================================================================
// Build Header
//-----------------------------------------------------------------------------
// RFC 2616 / 6 Response (Header)
//
//   The first line of a Response message is the Status-Line, consisting
//   of the protocol version followed by a numeric status code and its
//   associated textual phrase, with each element separated by SP
//   characters. No CR or LF is allowed except in the final CRLF sequence.
//
//	Response       =Status-Line		; generated by SendHeader
//			*(( general-header
//			 | response-header
//			 | entity-header ) CRLF)
//			 CRLF			; generated by SendHeader
//			 [ message-body ]	; by HOOK Handling Loop or Sendfile
//
//	Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF ; generated by SendHeader
//
//	general-header = Cache-Control             ; not implemented
//			| Connection               ; implemented
//			| Date                     ; implemented
//			| Pragma                   ; not implemented
//			| Trailer                  ; not implemented
//			| Transfer-Encoding        ; not implemented
//			| Upgrade                  ; not implemented
//			| Via                      ; not implemented
//			| Warning                  ; not implemented
//
//	response-header = Accept-Ranges          ; not implemented
//			| Age                     ; not implemented
//			| ETag                    ; not implemented
//			| Location                ; implemented (redirection / Object moved)
//			| Proxy-Authenticate      ; not implemented
//			| Retry-After             ; not implemented
//			| Server                  ; implemented
//			| Vary                    ; not implemented
//			| WWW-Authenticate        ; implemented (by mod_auth and SendHeader)
//
//	entity-header  = Allow                    ; not implemented
//			| Content-Encoding         ; not implemented
//			| Content-Language         ; not implemented
//			| Content-Length           ; implemented
//			| Content-Location         ; not implemented
//			| Content-MD5              ; not implemented
//			| Content-Range            ; not implemented
//			| Content-Type             ; implemented
//			| Expires                  ; not implemented
//			| Last-Modified            ; implemented for static files
//			| extension-header
//
//				extension-header = message-header
//=============================================================================
std::string CyhookHandler::BuildHeader(bool cache) {
	std::string result = "";

	const char *responseString = "";
	const char *infoString = 0;

	// get Info Index
	for (unsigned int i = 0; i < (sizeof(httpResponseNames)
			/ sizeof(httpResponseNames[0])); i++)
		if (httpResponseNames[i].type == httpStatus) {
			responseString = httpResponseNames[i].name;
			infoString = httpResponseNames[i].info;
			break;
		}
	// print Status-line
	result = string_printf(HTTP_PROTOCOL " %d %s\r\nContent-Type: %s\r\n",httpStatus, responseString, ResponseMimeType.c_str());
	log_level_printf(2, "Respose: HTTP/1.1 %d %s\r\nContent-Type: %s\r\n",
			httpStatus, responseString, ResponseMimeType.c_str());

	switch (httpStatus) {
	case HTTP_UNAUTHORIZED:
		result += "WWW-Authenticate: Basic realm=\"";
		result += AUTH_NAME_MSG "\r\n";
		break;

	case HTTP_MOVED_TEMPORARILY:
	case HTTP_MOVED_PERMANENTLY:
		// Status HTTP_*_TEMPORARILY (redirection)
		result += string_printf("Location: %s\r\n", NewURL.c_str());
		// NO break HERE !!!

	default:
		time_t timer = time(0);
		char timeStr[80];
		// cache
		if (!cache && (HookVarList["CacheCategory"]).empty())
			result += "Cache-Control: no-cache\r\n";
		else {
			time_t x_time = time(NULL);
			struct tm *ptm = gmtime(&x_time);
			ptm->tm_mday += 1;
			x_time = mktime(ptm);
			strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&x_time));
			result += string_printf("Expires: %s\r\n", timeStr);
		}
		result += "Server: " WEBSERVERNAME "\r\n";
		// actual date
		strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&timer));
		result += string_printf("Date: %s\r\n", timeStr);
		// connection type
#ifdef Y_CONFIG_FEATURE_KEEP_ALIVE
		if(keep_alive)
		result += "Connection: keep-alive\r\n";
		else
		result += "Connection: close\r\n";
#else
		result += "Connection: close\r\n";
#endif
		// gzipped ?
		if (UrlData["fileext"] == "gz")
			result += "Content-Encoding: gzip\r\n";
		// content-len, last-modified
		if (httpStatus == HTTP_NOT_MODIFIED || httpStatus == HTTP_NOT_FOUND)
			result += "Content-Length: 0\r\n";
		else if (GetContentLength() > 0) {
			time_t mod_time = time(NULL);
			if (LastModified != (time_t) - 1)
				mod_time = LastModified;

			strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&mod_time));
			result += string_printf(
					"Last-Modified: %s\r\nContent-Length: %ld\r\n", timeStr,
					GetContentLength());
		}
		result += "\r\n"; // End of Header
		break;
	}

	// Body
	if (Method != M_HEAD)
		switch (httpStatus) {
		case HTTP_OK:
		case HTTP_NOT_MODIFIED:
		case HTTP_CONTINUE:
		case HTTP_ACCEPTED:
		case HTTP_NO_CONTENT:
		case HTTP_NOT_FOUND:
		case HTTP_INTERNAL_SERVER_ERROR:
			break;

		case HTTP_MOVED_TEMPORARILY:
		case HTTP_MOVED_PERMANENTLY:
			result += "<html><head><title>Object moved</title></head><body>";
			result
					+= string_printf(
							"302 : Object moved.<br/>If you dont get redirected click <a href=\"%s\">here</a></body></html>\n",
							NewURL.c_str());
			break;

		default:
			// Error pages
			break;
		}
	return result;
}