1
1
#include " HttpsClient.hpp"
2
2
3
+ #pragma GCC diagnostic ignored "-Wpointer-arith"
4
+
3
5
#include < arpa/inet.h>
4
6
#include < openssl/err.h>
5
7
#include < unistd.h>
@@ -15,144 +17,196 @@ HttpsClient::HttpsClient() : Http() {
15
17
OPENSSL_init_ssl (OPENSSL_INIT_LOAD_SSL_STRINGS, NULL );
16
18
}
17
19
18
- bool HttpsClient::HandleFetchRequest (struct Request *request, bool ipv4) {
19
- /*
20
- std::string url((char *)request->iov[0].iov_base);
20
+ bool HttpsClient::HandleFetchRequest (struct Request *inner, bool ipv4) {
21
+ std::string url ((char *)inner->iov [2 ].iov_base );
21
22
url = url.substr (1 );
22
23
std::size_t pos = url.find (" /" );
23
24
std::string host = url.substr (0 , pos);
24
25
std::string query = url.substr (pos);
25
26
26
27
Log (__FILE__, __LINE__) << query;
27
28
28
- struct sockaddr_in6 *client =
29
- (struct sockaddr_in6 *)request->iov[4].iov_base;
30
-
31
29
const SSL_METHOD *method = TLS_client_method ();
32
30
SSL_CTX *ctx = SSL_CTX_new (method);
33
31
if (!ctx) {
34
32
Log (__FILE__, __LINE__, Log::kError ) << " Error creating context ssl" ;
35
- cache_ ->ReleaseErrorAllWaitingRequest(request , 502);
36
- return 1 ;
33
+ stream_ ->ReleaseErrorAllWaitingRequest (inner-> resource_id , 502 );
34
+ return false ;
37
35
}
38
36
39
37
SSL *ssl = SSL_new (ctx);
40
38
if (!ssl) {
41
39
CloseSSL (-1 , nullptr , ctx);
42
40
Log (__FILE__, __LINE__, Log::kError ) << " Error creating ssl" ;
43
- cache_->ReleaseErrorAllWaitingRequest(request, 502);
44
- Utils::ReleaseRequest(request);
45
- return -1;
41
+ stream_->ReleaseErrorAllWaitingRequest (inner->resource_id , 502 );
42
+ return false ;
43
+ }
44
+
45
+ int socket_fd = -1 ;
46
+ int is_connected = -1 ;
47
+
48
+ if (ipv4) {
49
+ struct sockaddr_in *client = (struct sockaddr_in *)inner->iov [4 ].iov_base ;
50
+ socket_fd = socket (AF_INET, SOCK_STREAM, 0 );
51
+ if (socket_fd > 0 ) {
52
+ is_connected = connect (socket_fd, (struct sockaddr *)client,
53
+ sizeof (struct sockaddr_in ));
54
+ }
55
+ } else {
56
+ struct sockaddr_in6 *client =
57
+ (struct sockaddr_in6 *)inner->iov [4 ].iov_base ;
58
+ socket_fd = socket (AF_INET6, SOCK_STREAM, 0 );
59
+ if (socket_fd > 0 ) {
60
+ is_connected = connect (socket_fd, (struct sockaddr *)client,
61
+ sizeof (struct sockaddr_in6 ));
62
+ }
46
63
}
47
64
48
- int socket_fd = socket(AF_INET6, SOCK_STREAM, 0);
49
65
if (socket_fd < 0 ) {
50
- CloseSSL(-1, ssl, ctx);
51
66
Log (__FILE__, __LINE__, Log::kError ) << " Error creating socket" ;
52
- cache_->ReleaseErrorAllWaitingRequest(request, 502);
53
- Utils::ReleaseRequest(request );
54
- return 1 ;
67
+
68
+ stream_-> ReleaseErrorAllWaitingRequest (inner-> resource_id , 502 );
69
+ return false ;
55
70
}
56
71
57
- if (connect(socket_fd, (struct sockaddr *)client,
58
- sizeof(struct sockaddr_in6)) < 0) {
72
+ if (is_connected < 0 ) {
59
73
CloseSSL (socket_fd, ssl, ctx);
60
74
Log (__FILE__, __LINE__, Log::kError ) << " Could not connect " ;
61
- cache_->ReleaseErrorAllWaitingRequest(request, 502);
62
- Utils::ReleaseRequest(request);
63
- return 1;
75
+ stream_->ReleaseErrorAllWaitingRequest (inner->resource_id , 502 );
76
+ return false ;
64
77
}
65
78
66
79
SSL_set_fd (ssl, socket_fd);
67
80
int err = SSL_connect (ssl);
68
81
if (err < 1 ) {
69
82
CloseSSL (socket_fd, ssl, ctx);
70
83
Log (__FILE__, __LINE__, Log::kError ) << " Could not connect " ;
71
- cache_->ReleaseErrorAllWaitingRequest(request, 502);
72
- Utils::ReleaseRequest(request);
73
- return 1;
84
+ stream_->ReleaseErrorAllWaitingRequest (inner->resource_id , 502 );
85
+ return false ;
74
86
}
75
87
76
88
std::stringstream ss;
77
89
ss << " GET " << query << " HTTP/1.2\r\n "
78
90
<< " Host: " << host << " \r\n "
79
- << "Accept: */ /* \r\n"
80
- << "Connection: close\r\n"
81
- << "\r\n\r\n";
91
+ << (char *)inner->iov [3 ].iov_base ;
82
92
std::string request_data = ss.str ();
83
93
84
94
if (SSL_write (ssl, request_data.c_str (), request_data.length ()) < 0 ) {
85
95
CloseSSL (socket_fd, ssl, ctx);
86
96
Log (__FILE__, __LINE__, Log::kError ) << " invalid socket" ;
87
- cache_->ReleaseErrorAllWaitingRequest(request, 502);
88
- Utils::ReleaseRequest(request);
89
- return 1;
97
+ stream_->ReleaseErrorAllWaitingRequest (inner->resource_id , 502 );
98
+ return false ;
90
99
}
91
100
92
- AddReadRequest(request, ssl, ctx, socket_fd);
93
- return 0;
94
- */
95
- return false ;
101
+ struct Request *http = Utils::HttpsExternalRequest (inner);
102
+ http->event_type = EVENT_TYPE_HTTP_READ_HEADER;
103
+ http->client_socket = socket_fd;
104
+ http->pivot = RESOURCE_TYPE_UNDEFINED;
105
+ http->iov [0 ].iov_base = malloc (buffer_size_);
106
+ http->iov [0 ].iov_len = buffer_size_;
107
+ memset (http->iov [0 ].iov_base , 0 , buffer_size_);
108
+ http->iov [1 ].iov_base = ssl;
109
+ http->iov [2 ].iov_base = ctx;
110
+
111
+ struct io_uring_sqe *sqe = io_uring_get_sqe (ring_);
112
+ // io_uring_prep_read(sqe, http->client_socket, http->iov[0].iov_base,
113
+ // buffer_size_, 0);
114
+ io_uring_prep_nop (sqe);
115
+ io_uring_sqe_set_data (sqe, http);
116
+ io_uring_submit (ring_);
117
+ return true ;
96
118
}
97
119
98
- void HttpsClient::AddReadRequest (struct Request *request, SSL *ssl,
99
- SSL_CTX *context, int fd) {
100
- // struct io_uring_sqe *sqe = io_uring_get_sqe(ring_);
120
+ int HttpsClient::ReadFromSSL (struct Request *http) {
121
+ SSL *ssl = (SSL *)http->iov [1 ].iov_base ;
122
+ int readed = SSL_read (ssl, http->iov [0 ].iov_base , buffer_size_);
123
+ if (readed < 1 ) {
124
+ if (!ProcessError (ssl, readed)) {
125
+ return -1 ;
126
+ }
127
+ if (readed == 0 ) {
128
+ return 0 ;
129
+ }
130
+ }
131
+ return readed;
132
+ }
133
+
134
+ int HttpsClient::HandleReadHeaderRequest (struct Request *http, int response) {
135
+ int readed = ReadFromSSL (http);
136
+ if (readed <= 0 ) {
137
+ if (readed < 0 ) {
138
+ stream_->ReleaseErrorAllWaitingRequest (http->resource_id , 502 );
139
+ } else {
140
+ stream_->CloseStream (http->resource_id );
141
+ }
142
+ ReleaseSocket (http);
143
+ return 1 ;
144
+ }
145
+
146
+ int type = GetResourceType ((char *)http->iov [0 ].iov_base , readed);
101
147
102
- // struct HttpRequest *http_request = new HttpRequest();
103
- // http_request->has_header = 0;
104
- // std::pair<int, struct HttpRequest *> item(fd, http_request);
105
- // waiting_read_.insert(item);
148
+ if (type == RESOURCE_TYPE_CACHE) {
149
+ int header_length =
150
+ FetchHeaderLength ((char *)http->iov [0 ].iov_base , readed);
106
151
107
- // struct Request *auxiliar = Utils::HttpsExternalRequest();
108
- // auxiliar->event_type = EVENT_TYPE_HTTP_READ;
109
- // auxiliar->client_socket = fd;
110
- // auxiliar->iov[0].iov_base = malloc(buffer_size_);
111
- // auxiliar->iov[0].iov_len = buffer_size_;
112
- // auxiliar->iov[1].iov_base = ssl;
113
- // auxiliar->iov[2].iov_base = context;
152
+ http->iov [0 ].iov_len = header_length;
153
+ cache_->GenerateNode (http);
154
+
155
+ if (header_length < readed) {
156
+ cache_->AppendBuffer (http->resource_id ,
157
+ http->iov [0 ].iov_base + header_length,
158
+ readed - header_length);
159
+ }
160
+ } else if (type == RESOURCE_TYPE_STREAMING) {
161
+ http->iov [0 ].iov_len = readed;
162
+ stream_->SetStreamingResource (http->resource_id , http);
163
+ }
114
164
115
- // memset(auxiliar->iov[0].iov_base, 0, buffer_size_);
165
+ struct io_uring_sqe *sqe = io_uring_get_sqe (ring_);
166
+ http->event_type = EVENT_TYPE_HTTP_READ_CONTENT;
167
+ http->pivot = type;
168
+ io_uring_prep_nop (sqe);
169
+ io_uring_sqe_set_data (sqe, http);
170
+ io_uring_submit (ring_);
116
171
117
- // io_uring_prep_nop(sqe);
118
- // io_uring_sqe_set_data(sqe, auxiliar);
119
- // io_uring_submit(ring_);
172
+ return 0 ;
120
173
}
121
174
122
- int HttpsClient::HandleReadData (struct Request *request, int response) {
123
- // SSL *ssl = (SSL *)request->iov[1].iov_base;
124
- // int err = SSL_read(ssl, request->iov[0].iov_base, buffer_size_);
125
- // if (err < 1) {
126
- // if (!ProcessError(ssl, err)) {
127
- // struct HttpRequest *http_request =
128
- // waiting_read_.at(request->client_socket);
129
- // //TODO(lanstat): verify when is finished
130
- // //cache_->ReleaseErrorAllWaitingRequest(http_request->request, 502);
131
- // ReleaseSocket(request);
132
- // return 1;
133
- // }
134
- // }
135
-
136
- // struct HttpRequest *http_request =
137
- // waiting_read_.at(request->client_socket); int readed =
138
- // FetchHeader(request->iov[0].iov_base); Log(__FILE__, __LINE__,
139
- // Log::kDebug) << "bytes readed: " << readed; if (readed <= 0) { struct
140
- // Request *client_request = UnifyBuffer(request); ReleaseSocket(request);
141
- // cache_->AddWriteRequest(client_request);
142
- // return 1;
143
- // } else {
144
- // struct iovec data;
145
- // data.iov_base = malloc(readed);
146
- // data.iov_len = readed;
147
- // memcpy(data.iov_base, request->iov[0].iov_base, readed);
148
- // }
149
-
150
- // memset(request->iov[0].iov_base, 0, buffer_size_);
151
-
152
- // struct io_uring_sqe *sqe = io_uring_get_sqe(ring_);
153
- // io_uring_prep_nop(sqe);
154
- // io_uring_sqe_set_data(sqe, request);
155
- // io_uring_submit(ring_);
175
+ int HttpsClient::HandleReadData (struct Request *http, int response) {
176
+ int type = http->pivot ;
177
+ int readed = ReadFromSSL (http);
178
+ if (readed <= 0 ) {
179
+ if (readed < 0 ) {
180
+ stream_->ReleaseErrorAllWaitingRequest (http->resource_id , 502 );
181
+ } else {
182
+ if (type == RESOURCE_TYPE_CACHE) {
183
+ cache_->CloseBuffer (http->resource_id );
184
+ } else if (type == RESOURCE_TYPE_STREAMING) {
185
+ stream_->CloseStream (http->resource_id );
186
+ }
187
+ }
188
+ ReleaseSocket (http);
189
+ return 1 ;
190
+ }
191
+
192
+ if (type == RESOURCE_TYPE_CACHE) {
193
+ cache_->AppendBuffer (http->resource_id , http->iov [0 ].iov_base , readed);
194
+ } else if (type == RESOURCE_TYPE_STREAMING) {
195
+ // If there is no listeners
196
+ if (stream_->NotifyStream (http->resource_id , http->iov [0 ].iov_base ,
197
+ readed) == 1 ) {
198
+ Log (__FILE__, __LINE__) << " HttpClient empty stream listeners" ;
199
+ ReleaseSocket (http);
200
+ return 1 ;
201
+ }
202
+ }
203
+
204
+ memset (http->iov [0 ].iov_base , 0 , buffer_size_);
205
+
206
+ struct io_uring_sqe *sqe = io_uring_get_sqe (ring_);
207
+ io_uring_prep_nop (sqe);
208
+ io_uring_sqe_set_data (sqe, http);
209
+ io_uring_submit (ring_);
156
210
157
211
return 0 ;
158
212
}
@@ -170,36 +224,28 @@ void HttpsClient::CloseSSL(int socket_fd, SSL *ssl, SSL_CTX *context) {
170
224
}
171
225
172
226
void HttpsClient::ReleaseSocket (struct Request *request) {
173
- // struct HttpRequest *http_request =
174
- // waiting_read_.at(request->client_socket);
175
- // waiting_read_.erase(request->client_socket);
176
-
177
- // free(request->iov[0].iov_base);
178
- // SSL *ssl = (SSL *)request->iov[1].iov_base;
179
- // SSL_CTX *context = (SSL_CTX *)request->iov[2].iov_base;
227
+ free (request->iov [0 ].iov_base );
228
+ SSL *ssl = (SSL *)request->iov [1 ].iov_base ;
229
+ SSL_CTX *context = (SSL_CTX *)request->iov [2 ].iov_base ;
180
230
181
- // CloseSSL(request->client_socket, ssl, context);
231
+ CloseSSL (request->client_socket , ssl, context);
182
232
183
- // delete http_request;
184
- // free(request);
233
+ free (request);
185
234
}
186
235
187
236
bool HttpsClient::ProcessError (SSL *ssl, int last_error) {
188
237
int error = SSL_get_error (ssl, last_error);
189
- Log (__FILE__, __LINE__, Log::kWarning ) << " SSL error " << error;
190
238
if (error == SSL_ERROR_NONE) {
191
239
// if (last_error == SSL_ERROR_SYSCALL) {
192
240
// return false;
193
241
// }
194
242
return true ;
195
243
} else if (error == SSL_ERROR_ZERO_RETURN) {
196
244
SSL_shutdown (ssl);
245
+ return true ;
197
246
} else if (error == SSL_ERROR_SYSCALL) {
247
+ Log (__FILE__, __LINE__, Log::kWarning ) << " SSL error " << error;
198
248
return ProcessError (ssl, error);
199
249
}
200
250
return false ;
201
251
}
202
-
203
- int HttpsClient::HandleReadHeaderRequest (struct Request *http, int readed) {
204
- return 0 ;
205
- }
0 commit comments