2
#include "client_manager.h"
4
#include "jpip/request.h"
5
#include "jpip/databin_server.h"
6
#include "http/header.h"
7
#include "http/response.h"
8
#include "net/socket_stream.h"
9
#include "jpeg2000/index_manager.h"
16
using namespace jpeg2000;
19
void ClientManager::Run(ClientInfo *client_info)
21
SocketStream sock_stream(client_info->sock());
22
string channel = base::to_string(client_info->base_id());
25
int buf_len = cfg.max_chunk_size();
27
char *buf = new char[buf_len];
30
ERROR("Insufficient memory to manage a new client session");
38
bool is_opened = false;
39
bool send_data = false;
40
ImageIndex::Ptr im_index;
41
DataBinServer data_server;
43
string backup_file = cfg.caching_folder() +
44
base::to_string(client_info->father_sock()) + ".backup";
46
if(File::Exists(backup_file.c_str())) {
47
InputStream().Open(backup_file.c_str()).Serialize(req.cache_model);
53
if(cfg.log_requests())
54
LOGC(_BLUE, "Waiting for a request ...");
56
if(cfg.com_time_out() > 0) {
57
if(sock_stream->WaitForInput(cfg.com_time_out() * 1000) == 0) {
58
LOG("Communication time-out");
65
if(getline(sock_stream, req_line).good())
66
com_error = !req.Parse(req_line);
69
if(sock_stream->IsValid()) LOG("Incorrect request received");
70
else LOG("Connection closed by the client");
75
if(cfg.log_requests())
76
LOGC(_BLUE, "Request: " << req_line);
79
int content_length = 0;
81
while((sock_stream >> header).good()) {
82
if(header == http::Header::ContentLength())
83
content_length = atoi(header.value.c_str());
86
if(req.type == http::Request::POST) {
90
while(content_length--)
91
body.put((char)sock_stream.get());
93
req.ParseParameters(body);
102
if (req.mask.items.cclose)
105
LOG("Close request received but there is not any channel opened");
106
else if(req.parameters["cclose"] != channel)
107
LOG("Close request received related to another channel");
111
req.cache_model.Clear();
112
unlink(backup_file.c_str());
113
index_manager.CloseImage(im_index);
114
LOG("The channel " << channel << " has been closed");
115
sock_stream << http::Response(200) << http::Header::ContentLength("0") << http::Protocol::CRLF << flush;
118
else if (req.mask.items.cnew)
121
LOG("There already is a channel opened. Only one channel per client is supported");
123
string file_name = (req.mask.items.target ? req.parameters["target"] : req.object);
125
if (!index_manager.OpenImage(file_name, &im_index))
126
ERROR("The image file '" << file_name << "' can not be read");
127
else if(!data_server.Reset(im_index))
128
ERROR("The image file '" << file_name << "' can not be opened");
129
else if(!data_server.SetRequest(req))
130
ERROR("The server can not process the request");
132
LOG("The channel " << channel << " has been opened for the image '" << file_name << "'");
135
<< http::Response(200)
136
<< http::Header("JPIP-cnew", "cid=" + channel + ",path=jpip,transport=http")
137
<< http::Header("JPIP-tid", index_manager.file_manager().GetCacheFileName(file_name))
138
<< http::Header::CacheControl("no-cache")
139
<< http::Header::TransferEncoding("chunked")
140
<< http::Header::ContentType("image/jpp-stream")
141
<< http::Protocol::CRLF
144
OutputStream().Open(backup_file.c_str()).Serialize(req.cache_model);
150
} else if (req.mask.items.cid) {
151
if(!is_opened) LOG("Request received but no channel is opened");
153
if(req.parameters["cid"] != channel)
154
LOG("Request related to another channel");
155
else if(!data_server.SetRequest(req))
156
ERROR("The server can not process the request");
159
<< http::Response(200)
160
<< http::Header::CacheControl("no-cache")
161
<< http::Header::TransferEncoding("chunked")
162
<< http::Header::ContentType("image/jpp-stream")
163
<< http::Protocol::CRLF
171
LOG("Invalid request (channel parameter not found)");
174
pclose = pclose && !send_data;
177
sock_stream << http::Response(500) << http::Protocol::CRLF << flush;
179
for(bool last = false; !last;) {
182
if(!data_server.GenerateChunk(buf, &chunk_len, &last)) {
183
ERROR("A new data chunk could not be generated");
189
sock_stream << hex << chunk_len << dec << http::Protocol::CRLF << flush;
191
//LOG("Chunk of " << chunk_len << " bytes sent");
192
sock_stream->Send(buf, chunk_len);
194
sock_stream << http::Protocol::CRLF << flush;
199
<< "0" << http::Protocol::CRLF
200
<< http::Protocol::CRLF
203
if(data_server.end_woi())
204
OutputStream().Open(backup_file.c_str()).Serialize(req.cache_model);
209
unlink(backup_file.c_str());
210
index_manager.CloseImage(im_index);
216
void ClientManager::RunBasic(ClientInfo *client_info)
220
char *buff = new char[buff_len];
221
SocketStream sock_stream(client_info->sock());
225
LOG("Waiting for a request ...");
227
if(cfg.com_time_out() > 0) {
228
if(sock_stream->WaitForInput(cfg.com_time_out() * 1000) == 0) {
229
LOG("Communication time-out");
230
sock_stream->Close();
235
if (!(sock_stream >> req).good())
237
if(sock_stream->IsValid()) LOG("Incorrect request received");
238
else LOG("Connection closed by the client");
239
sock_stream->Close();
246
while ((sock_stream >> header).good());
250
sock_stream << http::Response(200)
251
<< http::Header("JPIP-cnew", "cid=C0,path=jpip,transport=http")
252
<< http::Header("JPIP-tid", "T0")
253
<< http::Header::CacheControl("no-cache")
254
<< http::Header::ContentLength(base::to_string(buff_len))
255
<< http::Header::ContentType("image/jpp-stream")
256
<< http::Protocol::CRLF
259
sock_stream->Send(buff, buff_len);