00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "httpsrv.h"
00038
00039
00040 #ifdef _DEBUG
00041 #define HTML_FORMAT FORMAT_PRETTY
00042 #define HTML_PRETTY PRETTY_LINEFEED
00043 #else
00044 #define HTML_FORMAT FORMAT_PLAIN
00045 #define HTML_PRETTY PRETTY_PLAIN
00046 #endif
00047
00048
00049 #ifdef USE_HTTPAPI
00050
00051 #include <http.h>
00052 #pragma comment(lib, "httpapi")
00053
00054
00055 HttpServer::HttpServer()
00056 : _extensions(false)
00057 {
00058 HTTPAPI_VERSION version = HTTPAPI_VERSION_1;
00059
00060 ULONG ret = HttpInitialize(version, HTTP_INITIALIZE_SERVER, NULL);
00061 if (ret)
00062 throw WE(ret);
00063
00064 ret = HttpCreateHttpHandle(&_request, 0);
00065 if (ret)
00066 throw WE(ret);
00067 }
00068
00069 HttpServer::~HttpServer()
00070 {
00071 CloseHandle(_request);
00072
00073 HttpTerminate(HTTP_INITIALIZE_SERVER, NULL);
00074 }
00075
00076
00077 void HttpServer::register_url(LPCWSTR prefix)
00078 {
00079 ULONG ret = HttpAddUrl(_request, prefix, NULL);
00080 if (ret)
00081 throw WE(ret);
00082 }
00083
00084 void HttpServer::unregister_url(LPCWSTR prefix)
00085 {
00086 ULONG ret = HttpRemoveUrl(_request, prefix);
00087 if (ret)
00088 throw WE(ret);
00089 }
00090
00091
00092 struct HttpResponse : public HTTP_RESPONSE
00093 {
00094 HttpResponse(u_short code, const char* status_text)
00095 {
00096 memset(this, 0, sizeof(HTTP_RESPONSE));
00097
00098 StatusCode = code;
00099
00100 ReasonLength = strlen(status_text);
00101 pReason = status_text;
00102 }
00103
00104 void inline set_header(HTTP_HEADER_ID id, const char* str)
00105 {
00106 Headers.KnownHeaders[id].RawValueLength = strlen(str);
00107 Headers.KnownHeaders[id].pRawValue = str;
00108 }
00109 };
00110
00111 struct HttpData : public HTTP_DATA_CHUNK
00112 {
00113 template<typename T> HttpData(const T& str)
00114 {
00115 DataChunkType = HttpDataChunkFromMemory;
00116 FromMemory.pBuffer = (void*)str.c_str();
00117 FromMemory.BufferLength = str.length();
00118 }
00119 };
00120
00121
00122 void HttpServer::receive_request(HttpRequest& request)
00123 {
00124 ULONG buffer_len = 2048;
00125 PHTTP_REQUEST pReq = (PHTTP_REQUEST) alloca(buffer_len);
00126
00127 const HTTP_REQUEST_ID req_id = HTTP_NULL_ID;
00128
00129 ULONG received;
00130 ULONG ret = HttpReceiveHttpRequest(_request, req_id, 0, pReq, buffer_len, &received, NULL);
00131
00132 if (ret == ERROR_MORE_DATA) {
00133 buffer_len = received;
00134 pReq = (PHTTP_REQUEST) alloca(buffer_len);
00135
00136 ret = HttpReceiveHttpRequest(_request, req_id, 0, pReq, buffer_len, &received, NULL);
00137 }
00138
00139 if (ret)
00140 throw WE(ret);
00141
00142 request._id = pReq->RequestId;
00143
00144 if (pReq->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS) {
00145 char buffer[BUFFER_LEN];
00146 buffer_len = sizeof(buffer);
00147
00148 ret = HttpReceiveRequestEntityBody(_request, pReq->RequestId, 0, buffer, buffer_len, &received, NULL);
00149
00150 if (ret)
00151 throw WE(ret);
00152
00153 request._data.assign(buffer, received);
00154 }
00155
00156 if (pReq->Verb == HttpVerbGET)
00157 request._command = HTTP_GET;
00158 else if (pReq->Verb == HttpVerbPOST)
00159 request._command = HTTP_POST;
00160 else
00161 request._command = HTTP_UNKNOWN;
00162 }
00163
00164
00165 void HttpServer::send_response(HttpRequest& request, const string& str, const char* content_type)
00166 {
00167 HttpResponse response(200, "OK");
00168
00169 response.set_header(HttpHeaderServer, "XMLStorage XMLRPC");
00170 response.set_header(HttpHeaderContentType, content_type);
00171
00172 HttpData data(str);
00173
00174 response.EntityChunkCount = 1;
00175 response.pEntityChunks = &data;
00176
00177 ULONG ret = HttpSendHttpResponse(_request, request._id, HTTP_SEND_RESPONSE_FLAG_DISCONNECT,
00178 &response, NULL, NULL, NULL, 0, NULL, NULL);
00179 if (ret)
00180 throw WE(ret);
00181 }
00182
00183 void HttpServer::send_error(HttpRequest& request, u_short code, const char* status_text)
00184 {
00185 HttpResponse response(code, status_text);
00186
00187 response.set_header(HttpHeaderServer, "XMLStorage XMLRPC");
00188 response.set_header(HttpHeaderContentType, "text/plain");
00189
00190 char buffer[BUFFER_LEN];
00191 sprintf(buffer, "%d - %s", code, status_text);
00192 string error_msg = buffer;
00193
00194 HttpData data(error_msg);
00195
00196 response.EntityChunkCount = 1;
00197 response.pEntityChunks = &data;
00198
00199 ULONG ret = HttpSendHttpResponse(_request, request._id, HTTP_SEND_RESPONSE_FLAG_DISCONNECT,
00200 &response, NULL, NULL, NULL, 0, NULL, NULL);
00201 if (ret)
00202 throw WE(ret);
00203 }
00204
00205
00206 #else // USE_HTTPAPI
00207
00208
00209 HttpServer::HttpServer()
00210 : _extensions(false)
00211 {
00212 }
00213
00214 HttpServer::~HttpServer()
00215 {
00216 }
00217
00218
00219 void HttpServer::register_url(const char* prefix)
00220 {
00221 URL parsed_url(prefix);
00222
00223 if (!parsed_url._hostname.empty() && parsed_url._hostname!="+")
00224
00225 _addr.resolve(parsed_url._hostname.c_str(), parsed_url._port.c_str(), 0);
00226 else
00227
00228 _addr.resolve(NULL, parsed_url._port.c_str(), AI_PASSIVE);
00229
00230 _url_prefix = parsed_url._path;
00231
00232 _listen_socket.bind(_addr);
00233 }
00234
00235 void HttpServer::unregister_url(const char* prefix)
00236 {
00237 URL parsed_url(prefix);
00238
00239 if (parsed_url._path == _url_prefix) {
00240 _listen_socket.close();
00241 _addr.clear();
00242 _url_prefix.erase();
00243 }
00244 }
00245
00246
00247 void HttpServer::receive_request(HttpRequest& request)
00248 {
00249 do {
00250 if (_conn_socket == INVALID_SOCKET) {
00251 if (listen(_listen_socket, 4) < 0)
00252 throw LWSE();
00253
00254 SOCKADDR_IN sin;
00255 socklen_t sin_len = sizeof(sin);
00256
00257 SOCKET accept_socket = accept(_listen_socket, (struct sockaddr*)&sin, &sin_len);
00258
00259 if (accept_socket != INVALID_SOCKET)
00260 _conn_socket.init(accept_socket);
00261 }
00262 } while(!handle_request(request));
00263 }
00264
00265 bool HttpServer::handle_request(HttpRequest& request)
00266 {
00267 SocketReader reader(_conn_socket);
00268
00269
00270 char line[BUFFER_LEN];
00271
00272 if (reader.read_line(line, BUFFER_LEN) <= 0) {
00273
00274 _conn_socket.close();
00275 return false;
00276 }
00277
00278 char command[32];
00279 char path[BUFFER_LEN];
00280 char version[12];
00281
00282 #ifdef __STDC_WANT_SECURE_LIB__
00283 if (sscanf_s(line, "%s %s %s", command, _countof(command), path, _countof(path), version, _countof(version)) != 3)
00284 #else
00285 if (sscanf(line, "%s %s %s", command, path, version) != 3)
00286 #endif
00287 throw Exception("invalid HTML server response");
00288
00289 if (!_stricmp(command, "GET"))
00290 request._command = HTTP_GET;
00291 else if (!_stricmp(command, "POST"))
00292 request._command = HTTP_POST;
00293 else
00294 request._command = HTTP_UNKNOWN;
00295
00296
00297
00298 int content_length = 0;
00299 string content_type;
00300
00301
00302 for(;;) {
00303 if (reader.read_line(line, BUFFER_LEN) <= 0)
00304 break;
00305
00306 if (!_strnicmp(line, "Content-length:", 15))
00307 content_length = atoi(line+15);
00308 else if (!_strnicmp(line, "Content-type:", 13))
00309 content_type = line+14;
00310
00311
00312 }
00313
00314 if (!content_type.empty() && _strnicmp(content_type.c_str(),"text/xml",8) &&
00315 _strnicmp(content_type.c_str(),"application/x-www-form-urlencoded",33)) {
00316 char b[BUFFER_LEN];
00317 sprintf(b, "illegal content type: %s", content_type.c_str());
00318 throw Exception(b);
00319 }
00320
00321 if (content_length) {
00322 request._data.resize(content_length);
00323 reader.read(&request._data.at(0), content_length);
00324 }
00325
00326 return true;
00327 }
00328
00329
00330 void HttpServer::send_response(HttpRequest& request, const string& str, const char* content_type)
00331 {
00332 send(200, "OK", str, content_type, !_extensions);
00333 }
00334
00335 void HttpServer::send_error(HttpRequest& request, u_short code, const char* status_text)
00336 {
00337 char buffer[BUFFER_LEN];
00338 sprintf(buffer, "%d - %s", code, status_text);
00339 string error_msg = buffer;
00340
00341 send(code, status_text, error_msg, "text/plain", true);
00342 }
00343
00344
00345 void HttpServer::send(u_short code, const char* status_text, const string& data, const char* content_type, bool connection_close)
00346 {
00347
00348 ostringstream buffer;
00349
00350 buffer << "HTTP/1.1 200 OK\r\n";
00351 buffer << "Server: XMLStorage XMLRPC\r\n";
00352 buffer << "Content-length: " << data.length() << "\r\n";
00353 buffer << "Content-type: " << content_type << "\r\n";
00354
00355
00356 if (connection_close)
00357 buffer << "Connection: close\r\n";
00358
00359 buffer << "\r\n";
00360
00361 const string& header = buffer.str();
00362 _conn_socket.send(header.c_str(), header.length());
00363
00364
00365 _conn_socket.send(data.c_str(), data.length());
00366
00367 if (connection_close)
00368 _conn_socket.close();
00369 }
00370
00371 #endif // USE_HTTPAPI
00372
00373
00374 struct HTMLFormat : public XMLFormat
00375 {
00376 HTMLFormat()
00377 {
00378 _pretty = HTML_PRETTY;
00379
00380 _doctype._name = "html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
00381 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"";
00382 }
00383 };
00384
00385 struct HTMLWriter : public XMLWriter
00386 {
00387 HTMLWriter(ostream& out)
00388 : XMLWriter(out, HTMLFormat())
00389 {
00390 }
00391
00392 private:
00393 ostringstream _buffer;
00394 };
00395
00396
00397 static string get_html_page(XMLDoc& html_doc)
00398 {
00399 ostringstream ostr;
00400
00401 html_doc._format._doctype._name =
00402 "html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
00403 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"";
00404
00405 html_doc.write(ostr, HTML_FORMAT);
00406
00407 return ostr.str();
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505