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 using namespace BPrivate::Network; 17 18 19 BNetworkRequest::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 29 status_t 30 BNetworkRequest::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 43 void 44 BNetworkRequest::SetTimeout(bigtime_t timeout) 45 { 46 if (fSocket != NULL) 47 fSocket->SetTimeout(timeout); 48 } 49 50 51 bool 52 BNetworkRequest::_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 72 static void 73 empty(int) 74 { 75 } 76 77 78 void 79 BNetworkRequest::_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 93 status_t 94 BNetworkRequest::_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