1/* 2 * Copyright 2010-2014 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Christophe Huriaux, c.huriaux@gmail.com 7 * Niels Sascha Reedijk, niels.reedijk@gmail.com 8 * Adrien Destugues, pulkomandy@pulkomandy.tk 9 */ 10 11 12#include <NetworkRequest.h> 13 14#include <AbstractSocket.h> 15 16using namespace BPrivate::Network; 17 18 19BNetworkRequest::BNetworkRequest(const BUrl& url, BDataIO* output, 20 BUrlProtocolListener* listener, BUrlContext* context, 21 const char* threadName, const char* protocolName) 22 : 23 BUrlRequest(url, output, listener, context, threadName, protocolName), 24 fSocket(NULL) 25{ 26} 27 28 29status_t 30BNetworkRequest::Stop() 31{ 32 status_t threadStatus = BUrlRequest::Stop(); 33 34 if (threadStatus != B_OK) 35 return threadStatus; 36 37 send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls. 38 wait_for_thread(fThreadId, &threadStatus); 39 return threadStatus; 40} 41 42 43void 44BNetworkRequest::SetTimeout(bigtime_t timeout) 45{ 46 if (fSocket != NULL) 47 fSocket->SetTimeout(timeout); 48} 49 50 51bool 52BNetworkRequest::_ResolveHostName(BString host, uint16_t port) 53{ 54 _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s", 55 fUrl.UrlString().String()); 56 57 fRemoteAddr = BNetworkAddress(host, port); 58 if (fRemoteAddr.InitCheck() != B_OK) 59 return false; 60 61 //! ProtocolHook:HostnameResolved 62 if (fListener != NULL) 63 fListener->HostnameResolved(this, fRemoteAddr.ToString().String()); 64 65 _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s", 66 fRemoteAddr.ToString().String()); 67 68 return true; 69} 70 71 72static void 73empty(int) 74{ 75} 76 77 78void 79BNetworkRequest::_ProtocolSetup() 80{ 81 // Setup an (empty) signal handler so we can be stopped by a signal, 82 // without the whole process being killed. 83 // TODO make connect() properly unlock when close() is called on the 84 // socket, and remove this. 85 struct sigaction action; 86 action.sa_handler = empty; 87 action.sa_mask = 0; 88 action.sa_flags = 0; 89 sigaction(SIGUSR1, &action, NULL); 90} 91 92 93status_t 94BNetworkRequest::_GetLine(BString& destString) 95{ 96 // Find a complete line in inputBuffer 97 uint32 characterIndex = 0; 98 99 while ((characterIndex < fInputBuffer.Size()) 100 && ((fInputBuffer.Data())[characterIndex] != '\n')) 101 characterIndex++; 102 103 if (characterIndex == fInputBuffer.Size()) 104 return B_ERROR; 105 106 char* temporaryBuffer = new(std::nothrow) char[characterIndex + 1]; 107 if (temporaryBuffer == NULL) 108 return B_NO_MEMORY; 109 110 fInputBuffer.RemoveData(temporaryBuffer, characterIndex + 1); 111 112 // Strip end-of-line character(s) 113 if (characterIndex != 0 && temporaryBuffer[characterIndex - 1] == '\r') 114 destString.SetTo(temporaryBuffer, characterIndex - 1); 115 else 116 destString.SetTo(temporaryBuffer, characterIndex); 117 118 delete[] temporaryBuffer; 119 return B_OK; 120} 121 122 123