Ejemplo n.º 1
0
void
VolumeManager::OnLineRead(int aFd, nsDependentCSubstring& aMessage)
{
  MOZ_ASSERT(aFd == mSocket.get());
  char* endPtr;
  int responseCode = strtol(aMessage.Data(), &endPtr, 10);
  if (*endPtr == ' ') {
    endPtr++;
  }

  // Now fish out the rest of the line after the response code
  nsDependentCString  responseLine(endPtr, aMessage.Length() - (endPtr - aMessage.Data()));
  DBG("Rcvd: %d '%s'", responseCode, responseLine.Data());

  if (responseCode >= ::ResponseCode::UnsolicitedInformational) {
    // These are unsolicited broadcasts. We intercept these and process
    // them ourselves
    HandleBroadcast(responseCode, responseLine);
  } else {
    // Everything else is considered to be part of the command response.
    if (mCommands.size() > 0) {
      VolumeCommand* cmd = mCommands.front();
      cmd->HandleResponse(responseCode, responseLine);
      if (responseCode >= ::ResponseCode::CommandOkay) {
        // That's a terminating response. We can remove the command.
        mCommands.pop();
        mCommandPending = false;
        // Start the next command, if there is one.
        WriteCommandData();
      }
    } else {
      ERR("Response with no command");
    }
  }
}
const char*
HttpResponse::parseResponse(const char* buffer, size_t size)
{
  const char* curPos = buffer;

  const char* endline = (const char*)memmem(curPos, size - (curPos - buffer), "\r\n", 2);
  if (endline == 0)
    throw ParseError("HTTP response doesn't end with \\r\\n");

  string responseLine(curPos, endline - curPos);
  size_t posFirstSpace = responseLine.find(" ");
  size_t posSecondSpace = responseLine.find(" ", posFirstSpace + 1);

  if (posFirstSpace == string::npos || posSecondSpace == string::npos)
    throw ParseError("Incorrectly formatted response");

  // 1. HTTP version
  if (responseLine.compare(0, 5, "HTTP/") != 0)
    throw ParseError("Incorrectly formatted HTTP response");

  string version = responseLine.substr(5, posFirstSpace - 5);
  // TRACE(version);
  setVersion(version);

  // 2. Response code
  string code = responseLine.substr(posFirstSpace + 1, posSecondSpace - posFirstSpace - 1);
  // TRACE(code);
  setStatusCode(code);

  string msg = responseLine.substr(posSecondSpace + 1, responseLine.size() - posSecondSpace - 1);
  // TRACE(msg);
  setStatusMsg(msg);

  curPos = endline + 2;
  return parseHeaders(curPos, size - (curPos - buffer));
}
Ejemplo n.º 3
0
void
VolumeManager::OnFileCanReadWithoutBlocking(int aFd)
{
  MOZ_ASSERT(aFd == mSocket.get());
  while (true) {
    ssize_t bytesRemaining = read(aFd, &mRcvBuf[mRcvIdx], sizeof(mRcvBuf) - mRcvIdx);
    if (bytesRemaining < 0) {
      if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
        return;
      }
      if (errno == EINTR) {
        continue;
      }
      ERR("Unknown read error: %d (%s) - restarting", errno, strerror(errno));
      Restart();
      return;
    }
    if (bytesRemaining == 0) {
      // This means that vold probably crashed
      ERR("Vold appears to have crashed - restarting");
      Restart();
      return;
    }
    // We got some data. Each line is terminated by a null character
    DBG("Read %ld bytes", bytesRemaining);
    while (bytesRemaining > 0) {
      bytesRemaining--;
      if (mRcvBuf[mRcvIdx] == '\0') {
        // We found a line terminator. Each line is formatted as an
        // integer response code followed by the rest of the line.
        // Fish out the response code.
        char *endPtr;
        int responseCode = strtol(mRcvBuf, &endPtr, 10);
        if (*endPtr == ' ') {
          endPtr++;
        }

        // Now fish out the rest of the line after the response code
        nsDependentCString  responseLine(endPtr, &mRcvBuf[mRcvIdx] - endPtr);
        DBG("Rcvd: %d '%s'", responseCode, responseLine.Data());

        if (responseCode >= ResponseCode::UnsolicitedInformational) {
          // These are unsolicited broadcasts. We intercept these and process
          // them ourselves
          HandleBroadcast(responseCode, responseLine);
        } else {
          // Everything else is considered to be part of the command response.
          if (mCommands.size() > 0) {
            VolumeCommand *cmd = mCommands.front();
            cmd->HandleResponse(responseCode, responseLine);
            if (responseCode >= ResponseCode::CommandOkay) {
              // That's a terminating response. We can remove the command.
              mCommands.pop();
              mCommandPending = false;
              // Start the next command, if there is one.
              WriteCommandData();
            }
          } else {
            ERR("Response with no command");
          }
        }
        if (bytesRemaining > 0) {
          // There is data in the receive buffer beyond the current line.
          // Shift it down to the beginning.
          memmove(&mRcvBuf[0], &mRcvBuf[mRcvIdx + 1], bytesRemaining);
        }
        mRcvIdx = 0;
      } else {
        mRcvIdx++;
      }
    }
  }
}