예제 #1
0
void Audio_Stream::seekToTime(unsigned newSeekTime)
{
    unsigned duration = durationInSeconds();
    if (!(duration > 0)) {
        return;
    }
    
    close();
    
    setState(SEEKING);
    
    HTTP_Stream_Position position;
    double offset = (double)newSeekTime / (double)duration;
    position.start = m_dataOffset + offset * (contentLength() - m_dataOffset);
    position.end = contentLength();
    
    m_seekTime = newSeekTime;
    
    if (m_httpStream->open(position)) {
        AS_TRACE("%s: HTTP stream opened, buffering...\n", __PRETTY_FUNCTION__);
        m_httpStreamRunning = true;
    } else {
        AS_TRACE("%s: failed to open the HTTP stream\n", __PRETTY_FUNCTION__);
        setState(FAILED);
    }
}
예제 #2
0
void HexView::columnsChanged()
{
    int remainder = contentLength() % bytesPerRow();
    int rowCount = (remainder > 0) ? 1 : 0;

    setRowCount( rowCount + (  contentLength() / bytesPerRow() )  );
}
예제 #3
0
bool HttpClient::endOfBodyReached()
{
    if (endOfHeadersReached() && (contentLength() != kNoContentLengthHeader))
    {
        // We've got to the body and we know how long it will be
        return (iBodyLengthConsumed >= contentLength());
    }
    return false;
}
예제 #4
0
void Audio_Stream::seekToTime(unsigned newSeekTime)
{
    unsigned duration = durationInSeconds();
    if (!(duration > 0)) {
        return;
    }
    
    if (state() == SEEKING) {
        return;
    } else {
        setState(SEEKING);
    }
    
    m_seekTime = newSeekTime;
    
    double offset = (double)newSeekTime / (double)duration;
    UInt64 seekByteOffset = m_dataOffset + offset * (contentLength() - m_dataOffset);
    
    HTTP_Stream_Position position;

    position.start = seekByteOffset;
    position.end = contentLength();
    
    double packetDuration = m_srcFormat.mFramesPerPacket / m_srcFormat.mSampleRate;
    
    if (packetDuration > 0 && bitrate() > 0) {
        UInt32 ioFlags = 0;
        SInt64 packetAlignedByteOffset;
        SInt64 seekPacket = floor((double)newSeekTime / packetDuration);
        
        OSStatus err = AudioFileStreamSeek(m_audioFileStream, seekPacket, &packetAlignedByteOffset, &ioFlags);
        if (!err) {
            position.start = packetAlignedByteOffset + m_dataOffset;
        }
    }
    
    close();
    
    AS_TRACE("Seeking position %llu\n", position.start);
    
    if (m_httpStream->open(position)) {
        AS_TRACE("%s: HTTP stream opened, buffering...\n", __PRETTY_FUNCTION__);
        m_httpStreamRunning = true;
    } else {
        AS_TRACE("%s: failed to open the fHTTP stream\n", __PRETTY_FUNCTION__);
        setState(FAILED);
    }
}
예제 #5
0
void HexView::paint(QPainter *painter)
{
    int left = 0;
    int firstRow =  getRowForY( viewport_.y() )  - 1;
    int lastRow =  getRowForY( viewport_.y() + viewport_.height() )  + 1;

    if (firstRow <  0) firstRow = 0;
    if (lastRow >  rowCount() ) lastRow = rowCount();

    painter->setFont(QFont("Courier"));
    qDebug() << "contentlength=" << contentLength()  << " firstrow=" << firstRow << " lastRow=" << lastRow << " viewport="  << viewport_;

    if (showGuidelines_)    {
        QPen backpen(QColor(255,0,0));
        painter->setPen(backpen);
        //painter->drawRect(viewport_);
    }

    if (showOffsets()) {
        paintOffsets(painter,left,firstRow,lastRow);
    }

    if (showHex()) {
        paintHex(painter,left,firstRow,lastRow);
    }

    if (showAscii()) {
        paintAscii(painter,left,firstRow,lastRow);
    }

}
예제 #6
0
bool QHttpNetworkReplyPrivate::expectContent()
{
    // check whether we can expect content after the headers (rfc 2616, sec4.4)
    if ((statusCode >= 100 && statusCode < 200)
        || statusCode == 204 || statusCode == 304)
        return false;
    if (request.operation() == QHttpNetworkRequest::Head)
        return !shouldEmitSignals();
    if (contentLength() == 0)
        return false;
    return true;
}
예제 #7
0
// discard remainder of POST data
void HTTPHeader::discard(Socket *sock)
{
	static char fred[4096];
	off_t cl = contentLength() - postdatalen;
	int rc;
	while (cl > 0) {
		rc = sock->readFromSocket(fred, ((cl > 4096) ? 4096 : cl), 0, timeout, false);
		if (rc > 0)
			cl -= rc;
		else
			break;
	}
}
예제 #8
0
unsigned Audio_Stream::durationInSeconds()
{
    unsigned duration = 0;
    unsigned bitrate = m_audioQueue->bitrate();
    
    if (bitrate == 0) {
        goto out;
    }
    
    duration = contentLength() / (bitrate * 0.125);
    
out:
    return duration;
}
예제 #9
0
bool QHttpNetworkReplyPrivate::expectContent()
{
    // check whether we can expect content after the headers (rfc 2616, sec4.4)
    if ((statusCode >= 100 && statusCode < 200)
        || statusCode == 204 || statusCode == 304)
        return false;
    if (request.operation() == QHttpNetworkRequest::Head)
        return false; // no body expected for HEAD request
    qint64 expectedContentLength = contentLength();
    if (expectedContentLength == 0)
        return false;
    if (expectedContentLength == -1 && bodyLength == 0) {
        // The content-length header was stripped, but its value was 0.
        // This would be the case for an explicitly zero-length compressed response.
        return false;
    }
    return true;
}
예제 #10
0
String HttpClient::responseBody()
{
    int bodyLength = contentLength();
    String response;

    if (bodyLength > 0)
    {
        // try to reserve bodyLength bytes
        if (response.reserve(bodyLength) == 0) {
            // String reserve failed
            return String((const char*)NULL);
        }
    }

    // keep on timedRead'ing, until:
    //  - we have a content length: body length equals consumed or no bytes
    //                              available
    //  - no content length:        no bytes are available
    while (iBodyLengthConsumed != bodyLength)
    {
        int c = timedRead();

        if (c == -1) {
            // read timed out, done
            break;
        }

        if (!response.concat((char)c)) {
            // adding char failed
            return String((const char*)NULL);
        }
    }

    if (bodyLength > 0 && (unsigned int)bodyLength != response.length()) {
        // failure, we did not read in reponse content length bytes
        return String((const char*)NULL);
    }

    return response;
}
예제 #11
0
unsigned Audio_Stream::durationInSeconds()
{
    unsigned duration = 0;
    unsigned bitrate = this->bitrate();
    
    if (bitrate == 0) {
        goto out;
    }
    
    double d;
    
    if (m_audioDataByteCount > 0) {
        d = m_audioDataByteCount;
    } else {
        d = contentLength();
    }
    
    duration = d / (bitrate * 0.125);
    
out:
    return duration;
}
예제 #12
0
qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
{
    if (fragment.isEmpty()) {
        // according to http://dev.opera.com/articles/view/mama-http-headers/ the average size of the header
        // block is 381 bytes.
        // reserve bytes. This is better than always append() which reallocs the byte array.
        fragment.reserve(512);
    }

    qint64 bytes = 0;
    char c = 0;
    bool allHeaders = false;
    qint64 haveRead = 0;
    do {
        haveRead = socket->read(&c, 1);
        if (haveRead == 0) {
            // read more later
            break;
        } else if (haveRead == -1) {
            // connection broke down
            return -1;
        } else {
            fragment.append(c);
            bytes++;

            if (c == '\n') {
                // check for possible header endings. As per HTTP rfc,
                // the header endings will be marked by CRLFCRLF. But
                // we will allow CRLFCRLF, CRLFLF, LFLF
                if (fragment.endsWith("\r\n\r\n")
                    || fragment.endsWith("\r\n\n")
                    || fragment.endsWith("\n\n"))
                    allHeaders = true;

                // there is another case: We have no headers. Then the fragment equals just the line ending
                if ((fragment.length() == 2 && fragment.endsWith("\r\n"))
                    || (fragment.length() == 1 && fragment.endsWith("\n")))
                    allHeaders = true;
            }
        }
    } while (!allHeaders && haveRead > 0);

    // we received all headers now parse them
    if (allHeaders) {
        parseHeader(fragment);
        state = ReadingDataState;
        fragment.clear(); // next fragment
        bodyLength = contentLength(); // cache the length

        // cache isChunked() since it is called often
        chunkedTransferEncoding = headerField("transfer-encoding").toLower().contains("chunked");

        // cache isConnectionCloseEnabled since it is called often
        QByteArray connectionHeaderField = headerField("connection");
        // check for explicit indication of close or the implicit connection close of HTTP/1.0
        connectionCloseEnabled = (connectionHeaderField.toLower().contains("close") ||
            headerField("proxy-connection").toLower().contains("close")) ||
            (majorVersion == 1 && minorVersion == 0 &&
            (connectionHeaderField.isEmpty() && !headerField("proxy-connection").toLower().contains("keep-alive")));
    }
    return bytes;
}
예제 #13
0
파일: Reply.C 프로젝트: bend/wt
bool Reply::nextBuffers(std::vector<asio::const_buffer>& result)
{
  bufs_.clear();
  buf_.clear();
  postBuf_.clear();

  if (relay_.get())
    return relay_->nextBuffers(result);
  else {
    if (!transmitting_) {
      transmitting_ = true;
      bool http10 = (request_.http_version_major == 1)
	&& (request_.http_version_minor == 0);

      closeConnection_ = closeConnection_ || request_.closeConnection();

      /*
       * Status line.
       */

      buf_ << "HTTP/";
      buf_ << request_.http_version_major;
      buf_ << '.';
      buf_ << request_.http_version_minor;

      buf_ << ' ';

      status_strings::toText(buf_, status_);

      if (!http10 && status_ != switching_protocols) {
	/*
	 * Date header (current time)
	 */
	buf_ << "Date: ";
	httpDateBuf(time(0), buf_);
	buf_ << "\r\n";
      }

      /*
       * Content type or location
       */

      std::string ct;
      if (status_ >= 300 && status_ < 400) {
	if (!location().empty()) {
	  buf_ << "Location: " << location() << "\r\n";
	}
      } else if (status_ != not_modified && status_ != switching_protocols) {
	ct = contentType();
	buf_ << "Content-Type: " << ct << "\r\n";
      }

      /*
       * Other provided headers
       */
      bool haveContentEncoding = false;
      for (unsigned i = 0; i < headers_.size(); ++i) {
	if (headers_[i].first == "Content-Encoding")
	  haveContentEncoding = true;
	buf_ << headers_[i].first << ": " << headers_[i].second << "\r\n";
      }

      ::int64_t cl = -1;

      if (status_ != not_modified)
	cl = contentLength();
      else
	cl = 0;

      /*
       * We would need to figure out the content length based on the
       * response data, but this doesn't work: WtReply reuses the
       * same buffers over and over, expecting them to be sent
       * inbetween each call to nextContentBuffer()
       */
      if ((cl == -1) && http10)
	closeConnection_ = true;

      /*
       * Connection
       */
      if (closeConnection_ && request_.type == Request::HTTP) {
	buf_ << "Connection: close\r\n";
      } else {
	if (http10) {
	  buf_ << "Connection: keep-alive\r\n";
	}
      }

      if (status_ != not_modified) {
#ifdef WTHTTP_WITH_ZLIB
	/*
	 * Content-Encoding: gzip ?
	 */
	gzipEncoding_ = 
	     !haveContentEncoding
	  && configuration_.compression()
	  && request_.acceptGzipEncoding()
	  && (cl == -1)
	  && (ct.find("text/html") != std::string::npos
	      || ct.find("text/plain") != std::string::npos
	      || ct.find("text/javascript") != std::string::npos
	      || ct.find("text/css") != std::string::npos
	      || ct.find("application/xhtml+xml")!= std::string::npos
	      || ct.find("image/svg+xml")!= std::string::npos
	      || ct.find("application/octet")!= std::string::npos
	      || ct.find("text/x-json") != std::string::npos);

	if (gzipEncoding_) {
	  buf_ << "Content-Encoding: gzip\r\n";
	  
	  initGzip();
	}
#endif

	/*
	 * We do not need to determine the length of the response...
	 * Transmit only header first.
	 */
	if (cl != -1) {
	  buf_ << "Content-Length: " << (long long)cl << "\r\n";
	  chunkedEncoding_ = false;
	} else
	  if (closeConnection_)
	    chunkedEncoding_ = false; // should be false
	  else
	    if (!http10 && status_ != switching_protocols)
	      chunkedEncoding_ = true;

	if (chunkedEncoding_) {
	  buf_ << "Transfer-Encoding: chunked\r\n";
	}

	buf_ << "\r\n";

	return nextWrappedContentBuffers(result);
      } else { // status_ == not-modified
	buf_ << "\r\n";

	buf_.asioBuffers(result);
	return true;
      }
    } else { // transmitting (data)
      return nextWrappedContentBuffers(result);
    }
  }

  assert(false);

  return true;
}
예제 #14
0
// is this a POST request encapsulating a file upload?
bool HTTPHeader::isPostUpload(Socket &peersock)
{
	if (header.front().toCharArray()[0] != 'P') {
		return false;
	}

	/*bool answer = false;
	int postlen = postdata.buffer_length;
	int i;
	if (postlen < 14) {	// min length for there to be a match
		return false;
	}
	char *postdatablock = new char[postlen + 64];  // extra 64 for search
	try {
		postdata.copyToMemory(postdatablock);
		for (i = 0; i < postlen; i++) {	// make lowercase char by char
			if (isupper(postdatablock[i])) {
				postdatablock[i] = tolower(postdatablock[i]);
			}
		}
		RegExp mysearch;
		std::string dis("content-type: ");  // signifies file upload
		char *p = new char[32];
		try {
			for (i = 0; i < (signed) dis.length(); i++) {
				p[i] = dis[i];  // copy it to the block of memory
			}
			char *pend = p + dis.length();  // pointer for search
			char *postdatablockend = postdatablock + postlen;
			// search the post data for the content type header
			char *res = mysearch.search(postdatablock, postdatablockend, p, pend);
			// if we searched all the way to the end without finding it,
			// there is no post upload going on; otherwise, there is
			if (res != postdatablockend) {
				answer = true;
			}
		}
		catch(exception & e) {
		};
		delete[]p;
	}
	catch(exception & e) {
	};
	delete[]postdatablock;
	return answer;*/

	off_t cl = contentLength();
	if (((cl > 0) && (cl < 14)) || (getContentType() == "application/x-www-form-urlencoded")) {
#ifdef DGDEBUG
		std::cout << "Based on content length/type, is not POST upload!" << std::endl;
#endif
		ispostupload = false;
		return false;
	}
	if (getContentType().length() > 0) {
#ifdef DGDEBUG
		std::cout << "Based on content length/type, is POST upload!" << std::endl;
#endif
		ispostupload = true;
		return true;
	}

#ifdef DGDEBUG
	std::cout << "Reading a line of POST data to determine content type: ";
#endif
	postdatalen = peersock.getLine(postdata, 14, 60, &postdatachopped);
#ifdef DGDEBUG
	std::cout << postdata << std::endl;
#endif
	if (postdatalen != 14) {
#ifdef DGDEBUG
		std::cout << "Is not POST upload!" << std::endl;
#endif
		ispostupload = false;
		return false;
	}
	String conttype(postdata);
	if (conttype.startsWithLower("content-type: ")) {
#ifdef DGDEBUG
		std::cout << "Is POST upload!" << std::endl;
#endif
		ispostupload = true;
		return true;
	} else {
#ifdef DGDEBUG
		std::cout << "Is not POST upload!" << std::endl;
#endif
		ispostupload = false;
		return false;
	}
}
예제 #15
0
// send headers out over the given socket
// "reconnect" flag gives permission to reconnect to the socket on write error
// - this allows us to re-open the proxy connection on pconns if squid's end has
// timed out but the client's end hasn't. not much use with NTLM, since squid
// will throw a 407 and restart negotiation, but works well with basic & others.
void HTTPHeader::out(Socket * peersock, Socket * sock, int sendflag, bool reconnect) throw(std::exception)
{
	String l;  // for amalgamating to avoid conflict with the Nagel algorithm

	if (sendflag == __DGHEADER_SENDALL || sendflag == __DGHEADER_SENDFIRSTLINE) {
		if (header.size() > 0) {
			l = header.front() + "\n";
#ifdef DGDEBUG
			std::cout << "headertoclient:" << l << std::endl;
#endif
			// first reconnect loop - send first line
			while (true) {
				if (!(*sock).writeToSocket(l.toCharArray(), l.length(), 0, timeout)) {
					// reconnect & try again if we've been told to
					if (reconnect) {
						// don't try more than once
#ifdef DGDEBUG
						std::cout << "Proxy connection broken (1); trying to re-establish..." << std::endl;
						syslog(LOG_ERR,"Proxy connection broken (1); trying to re-establish...");
#endif
						reconnect = false;
						sock->reset();
						int rc = sock->connect(o.proxy_ip, o.proxy_port);
						if (rc)
							throw std::exception();
						continue;
					}
					throw std::exception();
				}
				// if we got here, we succeeded, so break the reconnect loop
				break;
			}
		}
		if (sendflag == __DGHEADER_SENDFIRSTLINE) {
			return;
		}
	}

	l = "";

	for (std::deque<String>::iterator i = header.begin() + 1; i != header.end(); i++) {
		l += (*i) + "\n";
	}
	l += "\r\n";

#ifdef DGDEBUG
	std::cout << "headertoclient:" << l << std::endl;
#endif

	// second reconnect loop
	while (true) {
		// send header to the output stream
		// need exception for bad write

		if (!(*sock).writeToSocket(l.toCharArray(), l.length(), 0, timeout)) {
			// reconnect & try again if we've been told to
			if (reconnect) {
				// don't try more than once
#ifdef DGDEBUG
				std::cout << "Proxy connection broken (2); trying to re-establish..." << std::endl;
				syslog(LOG_ERR,"Proxy connection broken (2); trying to re-establish...");
#endif
				reconnect = false;
				sock->reset();
				int rc = sock->connect(o.proxy_ip, o.proxy_port);
				if (rc)
					throw std::exception();
				// include the first line on the retry
				l = header.front() + "\n" + l;
				continue;
			}
			throw std::exception();
		}
		// if we got here, we succeeded, so break the reconnect loop
		break;
	}

	if ((!requestType().startsWith("HTTP")) && (pcontentlength != NULL)) {
		if (postdatalen > 0) {
#ifdef DGDEBUG
			std::cout << "Sending initial POST data chunk" << std::endl;
#endif
			// Re-add the chopped off \n, if necessary
			if (postdatachopped) {
#ifdef DGDEBUG
				std::cout << "Re-adding newline to POST data (postdatalen " << postdatalen << ")" << std::endl;
#endif
				postdata[postdatalen-1] = '\n';
				postdata[postdatalen] = '\0';
			}
			sock->writeToSockete(postdata, postdatalen, 0, timeout);
		}
#ifdef DGDEBUG
		std::cout << "Opening tunnel for remainder of POST data" << std::endl;
#endif
		FDTunnel fdt;
		off_t remaining = contentLength() - postdatalen;
		if (remaining < 0)
			throw std::runtime_error("No POST data left to send!?");
		fdt.tunnel(*peersock, *sock, false, remaining, true);
	}
}