HTTP errors while making a request through a proxy - c++

I want to know how to make an HTTP request through a proxy using Socket.
I was looking through documentation on Internet, and many people said that to do it I must connect to the proxy server and send a packet with the following header:
send(Socket, "CONNECT http://icanhazip.com:80 HTTP/1.0\r\n\r\n", strlen("CONNECT http://icanhazip.com:80 HTTP/1.0\r\n\r\n"), 0);
That website returns the current public IP, but, unfortunately, every proxy server I tried returned errors instead of the webpage's HTML source.
This is my actual code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
try {
int Socket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in SockAddr;
memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_port = htons(80);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = inet_addr("198.169.246.30");
int iResult = connect(Socket, (struct sockaddr *)& SockAddr, sizeof(SockAddr));
if (iResult != 0) {
std::cout << "I can't connect :(.";
getchar();
return 1;
}
std::cout << "Connected.\n";
send(Socket, "CONNECT http://icanhazip.com:80 HTTP/1.1\r\n\r\n", strlen("CONNECT http://icanhazip.com:80 HTTP/1.1\r\n\r\n"), 0);
char buffer[10000];
int nDataLength;
while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) {
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
std::cout << buffer[i];
i += 1;
}
}
iResult = close(Socket);
}
catch (...) {
}
return 0;
}
What can I do to fix it? Or, what other solution should I look into?

Old Chinese proverb say, "before writing code, better to read specification"
https://www.rfc-editor.org/rfc/rfc7230
by following links in the document:
A client sending a CONNECT request MUST send the authority form of
request-target (Section 5.3 of [RFC7230]); i.e., the request-target
consists of only the host name and port number of the tunnel
destination, separated by a colon. For example,
CONNECT server.example.com:80 HTTP/1.1
Host: server.example.com:80
source: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.6

Related

http request using sockets on c++

I'm trying to do an HTTP request using sockets on Linux, and my function works now, but only with simple domains as www.google.com or webpage.000webhostapp.com. When I try to add a path and query like webpage.000webhostapp.com/folder/file.php?parameter=value, it starts failing.
This is my code:
#include <iostream>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
int main(){
int socket_desc;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[4096];
std::string url = "www.exampleweb.com/folder/file.php";
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if(socket_desc < 0){
std::cout<<"failed to create socket"<<std::endl;
}
server = gethostbyname(url.c_str());
if(server==NULL){std::cout<<"could Not resolve hostname :("<<std::endl;}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(80);
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
if(connect(socket_desc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
std::cout<<"connection failed :("<<std::endl;
}
std::string request = "GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n";
if(send(socket_desc, request.c_str(), strlen(request.c_str())+1, 0) < 0){
std::cout<<"failed to send request..."<<std::endl;
}
int n;
std::string raw_site;
while((n = recv(socket_desc, buffer, sizeof(buffer)+1, 0)) > 0){
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'){
raw_site+=buffer[i];
i += 1;
}
}
std::cout<<raw_site<<std::endl;
return 0;
}
Using www.google.com, it works perfectly for the request.
Using www.example.com/folder/file.php?parameter=value&parameter2=value2, it fails and returns "could not resolve hostname".
Any idea on how to fix it?
I'm not using curl and can't use it for this project.
gethostbyname() (which BTW is deprecated, you should be using getaddrinfo() instead) does not work with URLs, only with host names.
Given a URL like http://www.exampleweb.com/folder/file.php?parameter=value&parameter2=value2, you need to first break it up into its constituent pieces (read RFC 3986), eg:
the scheme http
the host name www.exampleweb.com
the resource path /folder/file.php
the query ?parameter=value&parameter2=value2
You can then resolve the IP address for the host, connect to that IP address on port 80 (the default port for HTTP) since the URL doesn't specify a different port, and finally send a GET request for the resource and query.
Also, note that the Host header in the GET request must specify only the host name (and port, if different than the default), not the whole URL. And also that HTTP requests are not null-terminated strings, so do not send the null terminator. Read RFC 2616.
Try this instead:
#include <iostream>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
int main(){
int socket_desc;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[4096];
std::string host = "www.exampleweb.com";
std::string port = "80";
std::string resource = "/folder/file.php";
std::string query = "?parameter=value&parameter2=value2";
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc < 0){
std::cout << "failed to create socket" << std::endl;
return 0;
}
server = gethostbyname(host.c_str());
if (server == NULL){
std::cout << "could Not resolve hostname :(" << std::endl;
close(socket_desc);
return 0;
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(std::stoi(port));
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
if (connect(socket_desc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
std::cout << "connection failed :(" << std::endl;
close(socket_desc);
return 0;
}
std::string request = "GET " + resource + query + " HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n";
if (send(socket_desc, request.c_str(), request.size(), 0) < 0){
std::cout << "failed to send request..." << std::endl;
close(socket_desc);
return 0;
}
int n;
std::string raw_site;
while ((n = recv(socket_desc, buffer, sizeof(buffer), 0)) > 0){
raw_site.append(buffer, n);
}
close(socket_desc);
std::cout << raw_site << std::endl;
return 0;
}

C++ Sending vector<uchar> with socket loosing data

Im trying to send an Image with sockets from the server to the client, but for some reason im losing a lot of data.
this is my server:
#include <opencv2/imgcodecs.hpp>
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <string>
#define PORT 8080
using namespace cv;
using namespace std;
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
Mat image = cv::imread("Rio.jpg",IMREAD_COLOR); //BGR
std::vector< uchar > buf;
cv::imencode(".jpg",image,buf);
cerr << send(new_socket , buf.data() , buf.size(),0);
cerr << buf.data();
return 0;
}
The output of this file is:
562763����
562763 should be the size of data that is send to the client and ���� should be the data.
This is my Client:
#include <opencv2/imgcodecs.hpp>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <stdlib.h>
#include <netinet/in.h>
#include <iostream>
#define PORT 8080
using namespace std;
using namespace cv;
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
int l = 0;
std::string data = "";
do{
data += buffer;
l += strlen(buffer);
valread = read( sock , buffer, 1024);
}while(valread != 0);
cerr << l;
char* c = const_cast<char*>(data.c_str());
std::vector<uchar> vec(c,c+l);
Mat image2 = cv::imdecode(vec, 1);
// cv::imwrite("test22.jpg",image2);
return 0;
}
The output i get is:
87567Corrupt JPEG data: 175 extraneous bytes before marker 0xec
87567 should be the size of the data received and because there is data missing the jpeg cant be created
When im sending a message like "This is a test" the full text is received by the client.
You have two major flaws, one which could lead to an infinite loop, and one which leads to the problem you experience:
The infinite loop problem will happen if read fails in the client and it returns -1. -1 != 0, and then read will continue to read -1 forever.
The second and main problem is that you treat the data you send between the programs a strings which it is not. A "string" is a null-terminated (i.e. zero-terminated) sequence of characters, your image is not that. In fact, it might even contain embedded zeros inside the data which will give you invalid data in the middle as well.
To solve both problem I suggest you change the reading loop (and the variables used) to something like this:
uchar buffer[1024];
ssize_t read_result;
std::vector<uchar> data;
// While there's no error (read returns -1) or the connection isn't
// closed (read returns 0), continue to append the received data
// into the vector
while ((read_result = read(sock, buffer, sizeof buffer)) > 0)
{
// No errors, no closed connection
// Append the new data (and only the new data) at the end of the vector
data.insert(end(data), buffer, buffer + read_result);
}
After this loop, and if read_result == 0, then data should contain only the data that was sent. And all of it.
In your client you are using buffer before you have read anything to it. You also are assuming that it is null terminated.
Something like this seems better
std::string data = "";
for (;;)
{
valread = read( sock , buffer, 1024);
if (valread <= 0)
break;
data.append(buffer,valread);
}

UDP server client c++: sendto, recvfrom

I'm trying to complete a simple echo server. The goal is to repeat back the message to the client. The server and client both compile.The server is binded to localhost and port 8080. The client has the address, the port, and the message. When the client goes through the program to the sendto section, it stop and waits there. My goal it to have it sent to the server, and the server to send it back.
Problem: The client is send the message and the server is receiving it correctly but the server is not able to return the message. Please help!
SERVER SIDE CODE:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main() {
int serSockDes, len, readStatus;
struct sockaddr_in serAddr, cliAddr;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
exit(-1);
}
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
cout<<len;
sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, len);
return 0;
}
CLIENT SIDE CODE:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main(int argc, char** argv) {
int cliSockDes, readStatus, len;
struct sockaddr_in serAddr;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr));
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
return 0;
}
The client is trying to send its message to INADDR_ANY, which is wrong. It needs to send to a specific IP address instead. The server can listen to all of its local IP addresses using INADDR_ANY, that is fine, but the IP address that the client sends to must be one that the server listens on (or, if the client and server are on different network segments, the client must send to an IP that reaches the server's router, which then must forward the message to an IP that the server is listening on).
Also, your calls to recvfrom() and sendto() on both ends are lacking adequate error handling. In particular, the addrlen parameter of recvfrom() specifies the max size of the sockaddr buffer upon input, and upon output returns the actual size of the peer address stored in the sockaddr. But you are not initializing the len variable that you pass in as the addrlen, so recvfrom() is likely to fail with an error that you do not handle.
Try something more like this instead:
Server:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main() {
int serSockDes, readStatus;
struct sockaddr_in serAddr, cliAddr;
socklen_t cliAddrLen;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if ((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if ((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
close(serSockDes);
exit(-1);
}
cliAddrLen = sizeof(cliAddr);
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, &cliAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(serSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
if (sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, cliAddrLen)) < 0) {
perror("sending error...\n");
close(serSockDes);
exit(-1);
}
close(serSockDes);
return 0;
}
Client:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main(int argc, char** argv) {
int cliSockDes, readStatus;
struct sockaddr_in serAddr;
socklen_t serAddrLen;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if ((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr)) < 0) {
perror("sending error...\n");
close(cliSockDes);
exit(-1);
}
serAddrLen = sizeof(serAddr);
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, &serAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(cliSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
close(cliSockDes);
return 0;
}

how to check UDP Connection

Here I am checking UDP connection of IP address with specific port by using attached code. In my code if I give any IP and any port number it is getting connected successfully, the max range of port number is 5 digit but if I give more than 5 digit it will still get connection.
Major thing is on giving failure cases to check UDP Connection it passed that cases also.
failure cases i choosed:
1)not reachable IP
2)giving any port number
please help me to figure out what mistake i did in my code and what i can do in my code to check UDP connection is available for IP with specific port.My code attached below.
Thanks in Advance
#include <cstdlib>
#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <string.h>
#include <unistd.h>
using namespace std;
int main()
{
int sockfd,rv;
struct addrinfo *servinfo, *p,hints;
struct sockaddr_in *h;
string host ="172.30.36.150";
int port=8997345;
memset(&hints, 0, sizeof hints);
struct sockaddr_in clientService;
int serversockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serversockfd == -1) {
fprintf(stderr, "Error in socket %d\n", errno);
}
clientService.sin_family = AF_INET;
rv = getaddrinfo( host.c_str() , NULL , &hints , &servinfo);
string strhost = "";
if(rv ==0){
p = servinfo;
h = (struct sockaddr_in *) p->ai_addr;
char chost[INET_ADDRSTRLEN];
strcpy(chost , inet_ntoa( h->sin_addr ) );
strhost.append(chost);
freeaddrinfo(servinfo);
}
clientService.sin_addr.s_addr = inet_addr(strhost.c_str());
clientService.sin_port = htons((u_short)port);
int res = connect(serversockfd, (struct sockaddr*) &clientService,
sizeof(clientService));
close(serversockfd);
if (res == -1) {
fprintf(stderr, "Error connecting socket %d\n", errno);
}else{
cout<<"successfully connected"<<endl;
}
}

Making an HTTP Request with Sockets through a proxy

I would like to make an HTTP request using sockets. Here is my code so far:
#include "stdafx.h"
#ifndef UNICODE
#define UNICODE
#endif
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
try {
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
sockaddr_in clientService;
SOCKET Socket = socket(AF_INET, SOCK_STREAM, 0);
memset(&clientService, 0, sizeof(clientService));
clientService.sin_addr.s_addr = inet_addr("83.233.53.59"); // Proxy IP
clientService.sin_family = AF_INET;
clientService.sin_port = htons(10200);
if (bind(Socket, (struct sockaddr *) &clientService, sizeof(clientService)) < 0) {
perror("bind");
exit(1);
}
system("pause");
return 0;
struct hostent *host;
host = gethostbyname("www.google.com");
SOCKADDR_IN SockAddr;
SockAddr.sin_port = htons(80);
SockAddr.sin_family = AF_INET;
// SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
memcpy(host->h_addr, &(SockAddr.sin_addr.s_addr), host->h_length);
std::cout << "Connecting...\n";
iResult = connect(Socket, (SOCKADDR *)& clientService, sizeof(clientService));
if (iResult != 0) {
std::cout << "Could not connect";
getchar();
return 1;
}
std::cout << "Connected.\n";
send(Socket, "GET / HTTP / 1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n", strlen("GET / HTTP / 1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n"), 0);
char buffer[10000];
int nDataLength;
while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) {
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
std::cout << buffer[i];
i += 1;
}
}
iResult = closesocket(Socket);
WSACleanup();
system("pause");
}
catch (...) {
system("pause");
}
return 0;
}
But it doesn't work, without the program closes itself without leaving me the HTML source of the webpage. What's wrong?
How can I fix it?
This works on my machine, but I'm not on a windows machine. I'm on a freeBSD (OS X) machine. Having problems getting gethostbyname to resolve, not sure what that's about, but this worked and connected and downloaded the code from google.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
//#include <winsock2.h>
//#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
try {
// WSADATA wsaData;
// int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
// sockaddr_in clientService;
int Socket = socket(AF_INET, SOCK_STREAM, 0);
/*
memset(&clientService, 0, sizeof(clientService));
clientService.sin_addr.s_addr = inet_addr("83.233.53.59"); // Proxy IP
clientService.sin_family = AF_INET;
clientService.sin_port = htons(10200);
if (bind(Socket, (struct sockaddr *) &clientService, sizeof clientService) == -1) {
perror("bind");
exit(1);
}
system("pause");
return 0;
*/
const char hostname[] ="www.google.com";
struct hostent * host;
// host = gethostbyname(hostname);
sockaddr_in SockAddr;
memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_port = htons(80);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = inet_addr("83.233.53.59");
// memcpy(host->h_addr, &(SockAddr.sin_addr.s_addr), host->h_length);
std::cout << "Connecting...\n";
int iResult = connect(Socket, (struct sockaddr *)& SockAddr, sizeof(SockAddr));
if (iResult != 0) {
std::cout << "Could not connect";
getchar();
return 1;
}
std::cout << "Connected.\n";
send(Socket, "GET / HTTP / 1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n", strlen("GET / HTTP / 1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n"), 0);
char buffer[10000];
int nDataLength;
while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) {
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
std::cout << buffer[i];
i += 1;
}
}
iResult = close(Socket);
// WSACleanup();
system("pause");
}
catch (...) {
system("pause");
}
return 0;
}
It had an authentication failure at the http: level, but Heres the output:
Connecting...
Connected.
HTTP/1.0 401 Unauthorized
Server: uhttpd/1.0.0
Date: Thu, 17 Dec 2015 18:29:04 GMT
WWW-Authenticate: Basic realm=" "
Content-Type: text/html; charset="UTF-8"
Connection: close
<HTML><HEAD><META http-equiv='Pragma' content='no-cache'><META http-equiv='Cache-Control' content='no-cache'><TITLE> 401 Authorization</TITLE>
<script language=javascript type=text/javascript>
function cancelevent()
{
sh: pause: command not found
Program ended with exit code: 0
One thing that might go wrong is that your application may crash when it accesses an out-of-bound array index during the following loop:
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
...
i += 1;
}
Your current code cannot guarantee the buffer contains a byte that would make your loop terminate, therefore it might continue indefinitely. You must prevent this by having an extra check before accessing the array index. Considering that nDataLength will always be smaller or equal to sizeof(buffer), try this:
while (i < nDataLength &&
(buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'))
{
// Do your printing.
i++;
}
Or maybe simpler:
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r')
{
// Do your printing.
i++;
if (i >= nDataLength)
break; // Exit the loop.
}
system("pause");
return 0;
This code prevents anything following from executing. Remove.
There are numerous other problems with your code. For example, you're binding the socket to the proxy address. That doesn't make sense. Remove. You're about to connect the socket, you don't need to bind it at all.
Then you're sending an invalid GET request to the proxy. The GET request in this case should contain the full URL, not just a relative URL.
You're overrunning the receive buffer when you search for the space etc. You need to bound that search by the count returned by recv().
And so on.