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 16 17 #ifndef LIBNETAPI_DEPRECATED 18 using namespace BPrivate::Network; 19 #endif 20 21 22 #ifdef LIBNETAPI_DEPRECATED 23 BNetworkRequest::BNetworkRequest(const BUrl& url, BUrlProtocolListener* listener, 24 BUrlContext* context, const char* threadName, const char* protocolName) 25 : 26 BUrlRequest(url, listener, context, threadName, protocolName), 27 fSocket(NULL) 28 { 29 } 30 31 #else 32 33 BNetworkRequest::BNetworkRequest(const BUrl& url, BDataIO* output, 34 BUrlProtocolListener* listener, BUrlContext* context, 35 const char* threadName, const char* protocolName) 36 : 37 BUrlRequest(url, output, listener, context, threadName, protocolName), 38 fSocket(NULL) 39 { 40 } 41 #endif // LIBNETAPI_DEPRECATED 42 43 44 status_t 45 BNetworkRequest::Stop() 46 { 47 status_t threadStatus = BUrlRequest::Stop(); 48 49 if (threadStatus != B_OK) 50 return threadStatus; 51 52 send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls. 53 wait_for_thread(fThreadId, &threadStatus); 54 return threadStatus; 55 } 56 57 58 void 59 BNetworkRequest::SetTimeout(bigtime_t timeout) 60 { 61 if (fSocket != NULL) 62 fSocket->SetTimeout(timeout); 63 } 64 65 66 bool 67 BNetworkRequest::_ResolveHostName(BString host, uint16_t port) 68 { 69 _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s", 70 fUrl.UrlString().String()); 71 72 fRemoteAddr = BNetworkAddress(host, port); 73 if (fRemoteAddr.InitCheck() != B_OK) 74 return false; 75 76 //! ProtocolHook:HostnameResolved 77 if (fListener != NULL) 78 fListener->HostnameResolved(this, fRemoteAddr.ToString().String()); 79 80 _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s", 81 fRemoteAddr.ToString().String()); 82 83 return true; 84 } 85 86 87 static void 88 empty(int) 89 { 90 } 91 92 93 void 94 BNetworkRequest::_ProtocolSetup() 95 { 96 // Setup an (empty) signal handler so we can be stopped by a signal, 97 // without the whole process being killed. 98 // TODO make connect() properly unlock when close() is called on the 99 // socket, and remove this. 100 struct sigaction action; 101 action.sa_handler = empty; 102 action.sa_mask = 0; 103 action.sa_flags = 0; 104 sigaction(SIGUSR1, &action, NULL); 105 } 106 107 108 status_t 109 BNetworkRequest::_GetLine(BString& destString) 110 { 111 // Find a complete line in inputBuffer 112 uint32 characterIndex = 0; 113 114 while ((characterIndex < fInputBuffer.Size()) 115 && ((fInputBuffer.Data())[characterIndex] != '\n')) 116 characterIndex++; 117 118 if (characterIndex == fInputBuffer.Size()) 119 return B_ERROR; 120 121 char* temporaryBuffer = new(std::nothrow) char[characterIndex + 1]; 122 if (temporaryBuffer == NULL) 123 return B_NO_MEMORY; 124 125 fInputBuffer.RemoveData(temporaryBuffer, characterIndex + 1); 126 127 // Strip end-of-line character(s) 128 if (characterIndex != 0 && temporaryBuffer[characterIndex - 1] == '\r') 129 destString.SetTo(temporaryBuffer, characterIndex - 1); 130 else 131 destString.SetTo(temporaryBuffer, characterIndex); 132 133 delete[] temporaryBuffer; 134 return B_OK; 135 } 136 137 138