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