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