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
17BNetworkRequest::BNetworkRequest(const BUrl& url, BUrlProtocolListener* listener,
18		BUrlContext* context, const char* threadName, const char* protocolName)
19	:
20	BUrlRequest(url, listener, context, threadName, protocolName),
21	fSocket(NULL)
22{
23}
24
25
26status_t
27BNetworkRequest::Stop()
28{
29	status_t threadStatus = BUrlRequest::Stop();
30
31	if (threadStatus != B_OK)
32		return threadStatus;
33
34	send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls.
35	wait_for_thread(fThreadId, &threadStatus);
36	return threadStatus;
37}
38
39
40void
41BNetworkRequest::SetTimeout(bigtime_t timeout)
42{
43	if (fSocket != NULL)
44		fSocket->SetTimeout(timeout);
45}
46
47
48bool
49BNetworkRequest::_ResolveHostName(BString host, uint16_t port)
50{
51	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s",
52		fUrl.UrlString().String());
53
54	fRemoteAddr = BNetworkAddress(host, port);
55	if (fRemoteAddr.InitCheck() != B_OK)
56		return false;
57
58	//! ProtocolHook:HostnameResolved
59	if (fListener != NULL)
60		fListener->HostnameResolved(this, fRemoteAddr.ToString().String());
61
62	_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s",
63		fRemoteAddr.ToString().String());
64
65	return true;
66}
67
68
69static void
70empty(int)
71{
72}
73
74
75void
76BNetworkRequest::_ProtocolSetup()
77{
78	// Setup an (empty) signal handler so we can be stopped by a signal,
79	// without the whole process being killed.
80	// TODO make connect() properly unlock when close() is called on the
81	// socket, and remove this.
82	struct sigaction action;
83	action.sa_handler = empty;
84	action.sa_mask = 0;
85	action.sa_flags = 0;
86	sigaction(SIGUSR1, &action, NULL);
87}
88
89
90status_t
91BNetworkRequest::_GetLine(BString& destString)
92{
93	// Find a complete line in inputBuffer
94	uint32 characterIndex = 0;
95
96	while ((characterIndex < fInputBuffer.Size())
97		&& ((fInputBuffer.Data())[characterIndex] != '\n'))
98		characterIndex++;
99
100	if (characterIndex == fInputBuffer.Size())
101		return B_ERROR;
102
103	char* temporaryBuffer = new(std::nothrow) char[characterIndex + 1];
104	if (temporaryBuffer == NULL)
105		return B_NO_MEMORY;
106
107	fInputBuffer.RemoveData(temporaryBuffer, characterIndex + 1);
108
109	// Strip end-of-line character(s)
110	if (characterIndex != 0 && temporaryBuffer[characterIndex - 1] == '\r')
111		destString.SetTo(temporaryBuffer, characterIndex - 1);
112	else
113		destString.SetTo(temporaryBuffer, characterIndex);
114
115	delete[] temporaryBuffer;
116	return B_OK;
117}
118
119
120