Пример #1
0
bool Loader::readHeaders()
{
  MutexLock lock(program_binary_lock_);
  hdr_ = new Elf::Ehdr;

  if(readFromBinary((char*)hdr_, 0, sizeof(Elf::Ehdr)))
  {
    debug(LOADER, "Loader::readHeaders: ERROR! The headers could not be load.\n");
    return false;
  }

  //checking elf-magic-numbers, format (32/64bit) and a few more things
  if (!Elf::headerCorrect(hdr_))
  {
    debug(LOADER, "Loader::readHeaders: ERROR! The headers are invalid.\n");
    return false;
  }

  if(sizeof(Elf::Phdr) != hdr_->e_phentsize)
  {
    debug(LOADER, "Expected program header size does not match advertised program header size\n");
    return false;
  }
  phdrs_.resize(hdr_->e_phnum);
  if(readFromBinary(reinterpret_cast<char*>(&phdrs_[0]), hdr_->e_phoff, hdr_->e_phnum*sizeof(Elf::Phdr)))
  {
    return false;
  }
  if(!prepareHeaders())
  {
    debug(LOADER, "Loader::readHeaders: ERROR! There are no valid sections in the binary.\n");
    return false;
  }
  return true;
}
Пример #2
0
void GetClientHandler::handle(Client *client) {
	if (!client)
		return;
	if (!_headersPrepared)
		prepareHeaders();

	uint32 readBytes;

	// send headers first
	if (_headers.size() > 0) {
		readBytes = _headers.size();
		if (readBytes > CLIENT_HANDLER_BUFFER_SIZE)
			readBytes = CLIENT_HANDLER_BUFFER_SIZE;
		memcpy(_buffer, _headers.c_str(), readBytes);
		_headers.erase(0, readBytes);
	} else {
		if (!_stream) {
			client->close();
			return;
		}

		readBytes = _stream->read(_buffer, CLIENT_HANDLER_BUFFER_SIZE);
	}

	if (readBytes != 0)
		if (client->send(_buffer, readBytes) != readBytes) {
			warning("GetClientHandler: unable to send all bytes to the client");
			client->close();
			return;
		}

	// we're done here!
	if (_stream->eos())
		client->close();
}
Пример #3
0
void Transport::sendRawLocked(void *data, int size, int code /* = 200 */,
                              bool compressed /* = false */,
                              bool chunked /* = false */,
                              const char *codeInfo /* = "" */
                              ) {
  if (!compressed && RuntimeOption::ForceChunkedEncoding) {
    chunked = true;
  }
  if (m_chunkedEncoding) {
    chunked = true;
    assert(!compressed);
  } else if (chunked) {
    m_chunkedEncoding = true;
    assert(!compressed);
  }

  // I don't think there is any need to send an empty chunk, other than sending
  // out headers earlier, which seems to be a useless feature.
  if (chunked && size == 0) {
    return;
  }

  if (!m_headerCallbackDone && !m_headerCallback.isNull()) {
    // We could use m_headerSent here, however it seems we can still
    // end up in an infinite loop when:
    // m_headerCallback calls flush()
    // flush() triggers php's recursion guard
    // the recursion guard calls back into m_headerCallback
    m_headerCallbackDone = true;
    vm_call_user_func(m_headerCallback, null_array);
  }

  // compression handling
  ServerStatsHelper ssh("send");
  String response = prepareResponse(data, size, compressed, !chunked);

  if (m_responseCode < 0) {
    m_responseCode = code;
    m_responseCodeInfo = codeInfo ? codeInfo: "";
  }

  // HTTP header handling
  if (!m_headerSent) {
    String orig_response((const char *)data, size, CopyString);
    prepareHeaders(compressed, chunked, response, orig_response);
    m_headerSent = true;
  }

  m_responseSize += response.size();
  ServerStats::SetThreadMode(ServerStats::ThreadMode::Writing);
  sendImpl(response.data(), response.size(), m_responseCode, chunked);
  ServerStats::SetThreadMode(ServerStats::ThreadMode::Processing);

  ServerStats::LogBytes(size);
  if (RuntimeOption::EnableStats && RuntimeOption::EnableWebStats) {
    ServerStats::Log("network.uncompressed", size);
    ServerStats::Log("network.compressed", response.size());
  }
}
Пример #4
0
void Transport::sendRaw(void *data, int size, int code /* = 200 */,
                        bool compressed /* = false */,
                        bool chunked /* = false */,
                        const char *codeInfo /* = "" */
                       ) {
    ASSERT(data || size == 0);
    ASSERT(size >= 0);
    FiberWriteLock lock(this);

    if (!compressed && RuntimeOption::ForceChunkedEncoding) {
        chunked = true;
    }
    if (m_chunkedEncoding) {
        chunked = true;
        ASSERT(!compressed);
    } else if (chunked) {
        m_chunkedEncoding = true;
        ASSERT(!compressed);
    }

    // I don't think there is any need to send an empty chunk, other than sending
    // out headers earlier, which seems to be a useless feature.
    if (chunked && size == 0) {
        return;
    }

    // compression handling
    ServerStatsHelper ssh("send");
    String response = prepareResponse(data, size, compressed, !chunked);

    if (m_responseCode < 0) {
        m_responseCode = code;
        m_responseCodeInfo = codeInfo ? codeInfo: "";
    }

    // HTTP header handling
    if (!m_headerSent) {
        prepareHeaders(compressed, data, size);
        m_headerSent = true;
    }

    m_responseSize += response.size();
    ServerStats::SetThreadMode(ServerStats::Writing);
    sendImpl(response.data(), response.size(), m_responseCode, chunked);
    ServerStats::SetThreadMode(ServerStats::Processing);

    ServerStats::LogBytes(size);
    if (RuntimeOption::EnableStats && RuntimeOption::EnableWebStats) {
        ServerStats::Log("network.uncompressed", size);
        ServerStats::Log("network.compressed", response.size());
    }
}