-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweb-client-timeout.cpp
More file actions
134 lines (124 loc) · 3.45 KB
/
web-client-timeout.cpp
File metadata and controls
134 lines (124 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <string>
#include <thread>
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "httpRequest.h"
#include "httpResponse.h"
#include <iostream>
#include <fstream>
#include <sys/signal.h>
int _Fd;
volatile sig_atomic_t timeout = 0;
void signalrm_handler(int sig);
int main(int argc, char* argv[])
{
// Parse the argument
if(2 > argc) {
std::cerr << "Wrong number of arguments!" << std::endl;
return -1;
}
std::string hostname;
std::string port_str;
int port;
int pos1;
int pos2;
for(int i = 1; i < argc; i++) {
timeout = 0;
std::string url = argv[i];
pos1 = url.find(":", 7);
// No port specified default to 80
if(-1 == pos1) {
port = 80;
port_str = "80";
pos2 = url.find("/", 7);
if(-1 == pos2) {
continue;
}
hostname = url.substr(7, pos2 - 7);
}
else {
// Get all the characters after http:// up to the next colon
hostname = url.substr(7, pos1 - 7);
pos2 = url.find("/", pos1);
if(-1 == pos2) {
continue;
}
// Get the string after the hostname until the next /
port_str = url.substr(pos1 + 1, pos2 - pos1 - 1);
port = atoi(port_str.c_str());
}
// Get the rest of the strings after the port number
std::string filename = url.substr(pos2, -1);
// Initialize connection
struct hostent* server = gethostbyname(hostname.c_str());
if(0 == server) {
std::cerr << "Server not found" << std::endl;
return -1;
}
struct sockaddr_in serverAddress;
bzero((char *)&serverAddress, sizeof(serverAddress));
bcopy((char *)server->h_addr, (char *)&serverAddress.sin_addr.s_addr, server->h_length);
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
int socketFd = socket(AF_INET, SOCK_STREAM, 0);
int ret = connect(socketFd, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
if(ret < 0) {
std::cerr << "Error connecting" << std::endl;
return -1;
}
// Construct the request
HttpRequest request;
request.setUrl(filename);
request.setMethod("GET");
request.setHost(hostname);
request.setPort(port_str);
std::string blob = request.encode();
// set hostname and port
// set filename to get
// make a string
// Send the request
send(socketFd, blob.c_str(), blob.length() + 1, 0);
_Fd = socketFd;
// Get the response
std::string response = "";
char buf[4097] = {0};
signal(SIGALRM, &signalrm_handler);
alarm(60);
while(recv(socketFd, buf, 4096, 0) > 0) {
alarm(60);
response.append(buf);
memset(buf, 0, sizeof(buf));
}
if (timeout) {
continue;
}
// Interpret the response
HttpResponse resp;
if (response != "") {
resp.consume(response);
}
// find the last '/' character in the filename
int lastslash = filename.find_last_of('/');
filename = filename.substr(lastslash + 1, -1);
// If success, save the file in the current directory
if('2' == resp.status()[0] && resp.contentLength() == resp.message().length()) {
std::ofstream file;
file.open (filename);
file << resp.message();
file.close();
}
}
return 0;
}
void signalrm_handler(int sig) {
std::cerr << "Timeout occurring" << std::endl;
timeout = 1;
close(_Fd);
}