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