xref: /haiku/src/kits/network/libnetservices/NetworkRequest.cpp (revision d891ca1119fc87b4c4fef0baad9ebc49e22b94c9)
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