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