Ejemplo n.º 1
0
R_API RSocketHTTPRequest *r_socket_http_accept (RSocket *s, int timeout) {
	int content_length = 0, xx, yy;
	int pxx = 1, first = 0;
	char buf[1500], *p, *q;
	RSocketHTTPRequest *hr = R_NEW0 (RSocketHTTPRequest);
	hr->s = r_socket_accept (s);
	if (!hr->s) {
		free (hr);
		return NULL;
	}
	if (timeout>0)
		r_socket_block_time (hr->s, 1, timeout);
	for (;;) {
		memset (buf, 0, sizeof (buf));
		xx = r_socket_gets (hr->s, buf, sizeof (buf));
		yy = r_socket_ready (hr->s, 0, 20);
//		eprintf ("READ %d (%s) READY %d\n", xx, buf, yy);
		if (!yy || (!xx && !pxx)) {
			break;
		}
		pxx = xx;
		
		if (first==0) {
			first = 1;
			if (strlen (buf)<3) {
				r_socket_http_close (hr);
				return NULL;
			}
			p = strchr (buf, ' ');
			if (p) *p = 0;
			hr->method = strdup (buf);
			if (p) {
				q = strstr (p+1, " HTTP"); //strchr (p+1, ' ');
				if (q) *q = 0;
				hr->path = strdup (p+1);
			}
		} else {
			if (!hr->agent && !strncmp (buf, "User-Agent: ", 12)) {
				hr->agent = strdup (buf+12);
			} else
			if (!hr->host && !strncmp (buf, "Host: ", 6)) {
				hr->host = strdup (buf+6);
			} else
			if (!strncmp (buf, "Content-Length: ", 16)) {
				content_length = atoi (buf+16);
			}
		}
	}
	if (content_length>0) {
		r_socket_read_block (hr->s, (ut8*)buf, 1); // one missing byte wtf
		hr->data = malloc (content_length+1);
		hr->data_length = content_length;
		r_socket_read_block (hr->s, hr->data, hr->data_length);
		hr->data[content_length] = 0;
	}
	return hr;
}
Ejemplo n.º 2
0
static char *r_socket_http_answer (RSocket *s, int *code, int *rlen) {
	const char *p;
	int ret, olen, len = 0, bufsz = 32768, delta = 0;
	char *dn, *res, *buf = malloc (bufsz + 32); // XXX: use r_buffer here
	if (!buf) return NULL;

	r_socket_block_time (s, 1, 5);
	res = NULL;
	olen = r_socket_read_block (s, (unsigned char*) buf, bufsz);
	if (olen < 1) goto fail;
	buf[olen] = 0;
	if ((dn = (char*)r_str_casestr (buf, "\n\n"))) {
		delta += 2;
	} else if ((dn = (char*)r_str_casestr (buf, "\r\n\r\n"))) {
		delta += 4;
	} else goto fail;

	olen -= delta;
	*dn = 0; // chop headers
	/* Parse Len */
	p = r_str_casestr (buf, "Content-Length: ");
	if (p) len = atoi (p+16);
	else len = olen - (dn - buf);

	if (len >0) {
		if (len > olen) {
			res = malloc (len+2);
			memcpy (res, dn+delta, olen);
			do {
				ret = r_socket_read_block (s,
					(ut8*) res+olen, len-olen);
				if (ret < 1)
					break;
				olen += ret;
			} while (olen<len);
			res[len] = 0;
		} else {
			res = malloc (len+1);
			if (res) {
				memcpy (res, dn+delta, len);
				res[len] = 0;
			}
		}
	} else res = NULL;
fail:
	free (buf);
// is 's' free'd? isnt this going to cause a double free?
	r_socket_close (s);
	if (rlen) *rlen = len;
	return res;
}
Ejemplo n.º 3
0
static char *runcmd (const char *cmd) {
	char buf[4096] = {0};
	if (cmd) {
		r_socket_printf (gs, "%s\n", cmd);
	}
	int timeout = 1000000;
	char * str = NULL;
	r_socket_block_time (gs, 1, timeout);
	while (true) {
		memset (buf, 0, sizeof (buf));
		r_socket_read (gs, (ut8*)buf, sizeof (buf) - 1); // NULL-terminate the string always
		char *promptFound = strstr (buf, "Wine-dbg>");
		if (promptFound) {
			*promptFound = 0;
			return r_str_append (str, buf);
		}
		str = r_str_append (str, buf);
	}
	return NULL;
}
Ejemplo n.º 4
0
R_API int r_socket_connect (RSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
#if __WINDOWS__ && !defined(__CYGWIN__) && !defined(__MINGW64__)
	struct sockaddr_in sa;
	struct hostent *he;
	WSADATA wsadata;
	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
	s->fd = socket (AF_INET, SOCK_STREAM, 0);
	if (s->fd == -1)
		return false;

	memset (&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	he = (struct hostent *)gethostbyname (host);
	if (he == (struct hostent*)0) {
		close (s->fd);
		return false;
	}

	sa.sin_addr = *((struct in_addr *)he->h_addr);

	s->port = r_socket_port_by_name (port);
	sa.sin_port = htons (s->port);
#warning TODO: implement connect timeout on w32
	if (connect (s->fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr))) {
		close (s->fd);
		return false;
	}
	return true;
#elif __UNIX__ || defined(__CYGWIN__)
	int gai, ret;
	struct addrinfo hints, *res, *rp;
	if (!proto) proto = R_SOCKET_PROTO_TCP;
	signal (SIGPIPE, SIG_IGN);
	if (proto == R_SOCKET_PROTO_UNIX) {
		if (!r_socket_unix_connect (s, host))
			return false;
	} else {
		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
		hints.ai_protocol = proto;
		gai = getaddrinfo (host, port, &hints, &res);
		if (gai != 0) {
			//eprintf ("Error in getaddrinfo: %s\n", gai_strerror (gai));
			return false;
		}
		for (rp = res; rp != NULL; rp = rp->ai_next) {
			int flag = 1;

			s->fd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (s->fd == -1)
				continue;

			ret = setsockopt (s->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
			if (ret < 0) {
				close (s->fd);
				s->fd = -1;
				continue;
			}

			if (timeout>0) {
				r_socket_block_time (s, 1, timeout);
				//fcntl (s->fd, F_SETFL, O_NONBLOCK, 1);
			}
			ret = connect (s->fd, rp->ai_addr, rp->ai_addrlen);

			if (timeout == 0 && ret == 0) {
				freeaddrinfo (res);
				return true;

			} else if (ret == 0 /* || nonblocking */) {

				struct timeval tv;
				fd_set fdset, errset;
				FD_ZERO (&fdset);
				FD_SET (s->fd, &fdset);
				tv.tv_sec = 1; //timeout;
				tv.tv_usec = 0;

				if (r_socket_is_connected (s)) {
					freeaddrinfo (res);
					return true;
				}
				if (select (s->fd + 1, NULL, NULL, &errset, &tv) == 1) {
					int so_error;
					socklen_t len = sizeof so_error;
					ret = getsockopt (s->fd, SOL_SOCKET,
						SO_ERROR, &so_error, &len);

					if (ret == 0 && so_error == 0) {
						//fcntl (s->fd, F_SETFL, O_NONBLOCK, 0);
						//r_socket_block_time (s, 0, 0);
						freeaddrinfo (res);
						return true;
					}
				}
			}
			close (s->fd);
			s->fd = -1;
		}
		freeaddrinfo (res);
		if (rp == NULL) {
			eprintf ("Could not resolve address '%s'\n", host);
			return false;
		}
	}
#endif
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_client_method ());
		if (s->ctx == NULL) {
			r_socket_free (s);
			return false;
		}
		s->sfd = SSL_new (s->ctx);
		SSL_set_fd (s->sfd, s->fd);
		if (SSL_connect (s->sfd) != 1) {
			r_socket_free (s);
			return false;
		}
	}
#endif
	return true;
}
Ejemplo n.º 5
0
R_API bool r_socket_connect(RSocket *s, const char *host, const char *port, int proto, unsigned int timeout) {
#if __WINDOWS__
	struct sockaddr_in sa;
	struct hostent *he;
	WSADATA wsadata;
	TIMEVAL Timeout;
	Timeout.tv_sec = timeout;
	Timeout.tv_usec = 0;

	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
	s->fd = socket (AF_INET, SOCK_STREAM, 0);
#ifdef _MSC_VER
	if (s->fd == INVALID_SOCKET) {
#else
	if (s->fd == -1) {
#endif
		return false;
	}

	unsigned long iMode = 1;
	int iResult = ioctlsocket (s->fd, FIONBIO, &iMode);
	if (iResult != NO_ERROR) {
		eprintf ("ioctlsocket error: %d\n", iResult);
	}
	memset (&sa, 0, sizeof(sa));
	sa.sin_family = AF_INET;
	he = (struct hostent *)gethostbyname (host);
	if (he == (struct hostent*)0) {
#ifdef _MSC_VER
		closesocket (s->fd);
#else
		close (s->fd);
#endif
		return false;
	}
	sa.sin_addr = *((struct in_addr *)he->h_addr);
	s->port = r_socket_port_by_name (port);
	sa.sin_port = htons (s->port);
	if (!connect (s->fd, (const struct sockaddr*)&sa, sizeof (struct sockaddr))) {
#ifdef _MSC_VER
		closesocket (s->fd);
#else
		close (s->fd);
#endif
		return false;
	}
	iMode = 0;
	iResult = ioctlsocket (s->fd, FIONBIO, &iMode);
	if (iResult != NO_ERROR) {
		eprintf ("ioctlsocket error: %d\n", iResult);
	}
	if (timeout > 0) {
		r_socket_block_time (s, 1, timeout);
	}
	fd_set Write, Err;
	FD_ZERO (&Write);
	FD_ZERO (&Err);
	FD_SET (s->fd, &Write);
	FD_SET (s->fd, &Err);
	select (0, NULL, &Write, &Err, &Timeout);
	if (FD_ISSET (s->fd, &Write)) {
		return true;
	}
	return false;
#elif __UNIX__
	int ret;
	struct addrinfo hints = {0};
	struct addrinfo *res, *rp;
	if (!proto) {
		proto = R_SOCKET_PROTO_TCP;
	}
	signal (SIGPIPE, SIG_IGN);
	if (proto == R_SOCKET_PROTO_UNIX) {
		if (!r_socket_unix_connect (s, host)) {
			return false;
		}
	} else {
		hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
		hints.ai_protocol = proto;
		int gai = getaddrinfo (host, port, &hints, &res);
		if (gai != 0) {
			eprintf ("Error in getaddrinfo: %s\n", gai_strerror (gai));
			return false;
		}
		for (rp = res; rp != NULL; rp = rp->ai_next) {
			int flag = 1;

			s->fd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (s->fd == -1) {
				perror ("socket");
				continue;
			}
			ret = setsockopt (s->fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof (flag));
			if (ret < 0) {
				perror ("setsockopt");
				close (s->fd);
				s->fd = -1;
				continue;
			}
			if (timeout > 0) {
				r_socket_block_time (s, 1, timeout);
				//fcntl (s->fd, F_SETFL, O_NONBLOCK, 1);
			}
			ret = connect (s->fd, rp->ai_addr, rp->ai_addrlen);

			if (timeout == 0 && ret == 0) {
				freeaddrinfo (res);
				return true;
			}
			if (ret == 0 /* || nonblocking */) {
				struct timeval tv;
				fd_set fdset, errset;
				FD_ZERO (&fdset);
				FD_SET (s->fd, &fdset);
				tv.tv_sec = 1; //timeout;
				tv.tv_usec = 0;

				if (r_socket_is_connected (s)) {
					freeaddrinfo (res);
					return true;
				}
				if (select (s->fd + 1, NULL, NULL, &errset, &tv) == 1) {
					int so_error;
					socklen_t len = sizeof so_error;
					ret = getsockopt (s->fd, SOL_SOCKET,
						SO_ERROR, &so_error, &len);

					if (ret == 0 && so_error == 0) {
						//fcntl (s->fd, F_SETFL, O_NONBLOCK, 0);
						//r_socket_block_time (s, 0, 0);
						freeaddrinfo (res);
						return true;
					}
				}
			}
			close (s->fd);
			s->fd = -1;
		}
		freeaddrinfo (res);
		if (!rp) {
			eprintf ("Could not resolve address '%s' or failed to connect\n", host);
			return false;
		}
	}
#endif
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_client_method ());
		if (!s->ctx) {
			r_socket_free (s);
			return false;
		}
		s->sfd = SSL_new (s->ctx);
		SSL_set_fd (s->sfd, s->fd);
		if (SSL_connect (s->sfd) != 1) {
			r_socket_free (s);
			return false;
		}
	}
#endif
	return true;
}

/* close the file descriptor associated with the RSocket s */
R_API int r_socket_close_fd(RSocket *s) {
#ifdef _MSC_VER
	return s->fd != INVALID_SOCKET ? closesocket (s->fd) : false;
#else
	return s->fd != -1 ? close (s->fd) : false;
#endif
}

/* shutdown the socket and close the file descriptor */
R_API int r_socket_close(RSocket *s) {
	int ret = false;
	if (!s) {
		return false;
	}
	if (s->fd != -1) {
#if __UNIX__
		shutdown (s->fd, SHUT_RDWR);
#endif
#if __WINDOWS__
		// https://msdn.microsoft.com/en-us/library/windows/desktop/ms740481(v=vs.85).aspx
		shutdown (s->fd, SD_SEND);
		if (r_socket_ready (s, 0, 250)) {
			do {
				char buf = 0;
				ret = recv (s->fd, &buf, 1, 0);
			} while (ret != 0 && ret != SOCKET_ERROR);
		}
		ret = closesocket (s->fd);
#else
		ret = close (s->fd);
#endif
	}
#if HAVE_LIB_SSL
	if (s->is_ssl && s->sfd) {
		SSL_free (s->sfd);
		s->sfd = NULL;
	}
#endif
	return ret;
}