void nsGopherContentStream::OnCallbackPending() { nsresult rv; // We have a callback, so failure means we should close the stream. if (!mSocket) { rv = OpenSocket(CallbackTarget()); } else if (mSocketInput) { rv = mSocketInput->AsyncWait(this, 0, 0, CallbackTarget()); } if (NS_FAILED(rv)) CloseWithStatus(rv); }
nsresult nsGopherContentStream::OpenSocket(nsIEventTarget *target) { // This function is called to get things started. // We begin by opening a socket to the specified host and wait for the // socket to become writable. nsCAutoString host; nsresult rv = mChannel->URI()->GetAsciiHost(host); if (NS_FAILED(rv)) return rv; if (host.IsEmpty()) return NS_ERROR_MALFORMED_URI; // For security reasons, don't allow anything expect the default // gopher port (70). See bug 71916 - [email protected] PRInt32 port = GOPHER_PORT; // Create socket tranport nsCOMPtr<nsISocketTransportService> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; rv = sts->CreateTransport(nsnull, 0, host, port, mChannel->ProxyInfo(), getter_AddRefs(mSocket)); if (NS_FAILED(rv)) return rv; // Setup progress and status notifications rv = mSocket->SetEventSink(mChannel, target); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIOutputStream> output; rv = mSocket->OpenOutputStream(0, 0, GOPHER_MAX_WRITE_SEGMENT_COUNT, getter_AddRefs(output)); if (NS_FAILED(rv)) return rv; mSocketOutput = do_QueryInterface(output); NS_ENSURE_STATE(mSocketOutput); return mSocketOutput->AsyncWait(this, 0, 0, target); }
nsresult nsGopherContentStream::OnSocketWritable() { // Write to output stream (we can do this in one big chunk) nsresult rv = SendRequest(); if (NS_FAILED(rv)) return rv; // Open input stream nsCOMPtr<nsIInputStream> input; rv = mSocket->OpenInputStream(0, 0, 0, getter_AddRefs(input)); if (NS_FAILED(rv)) return rv; mSocketInput = do_QueryInterface(input, &rv); NS_ASSERTION(CallbackTarget(), "where is my pending callback?"); rv = mSocketInput->AsyncWait(this, 0, 0, CallbackTarget()); return rv; }