3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
24
/***************************************/
25
/****************************************************************************
27
* WebHttp.cc - code to process requests, and create responses
30
****************************************************************************/
33
#include "ink_platform.h"
34
#include "ink_unused.h" /* MAGIC_EDITING_TAG */
36
#include "SimpleTokenizer.h"
38
#include "WebCompatibility.h"
40
#include "WebHttpAuth.h"
41
#include "WebHttpContext.h"
42
#include "WebHttpLog.h"
43
#include "WebHttpMessage.h"
44
#include "WebHttpRender.h"
45
#include "WebHttpSession.h"
46
#include "WebHttpTree.h"
47
#include "WebOverview.h"
48
#include "WebConfig.h"
50
#include "INKMgmtAPI.h"
51
//#include "I_AccCrypto.h"
52
#include "LocalManager.h"
53
#include "WebMgmtUtils.h"
54
#include "MgmtUtils.h"
56
#include "CfgContextUtils.h"
58
#include "ConfigAPI.h"
61
#include "openssl/ssl.h"
62
#include "openssl/err.h"
63
#include "openssl/crypto.h"
65
// Ugly hack - define HEAP_H and STACK_H to prevent stuff from the
66
// template library from being included which SUNPRO CC does not not
70
#endif // !defined(_WIN32)
73
//-------------------------------------------------------------------------
75
//-------------------------------------------------------------------------
78
#define DIR_MODE S_IRWXU
79
#define FILE_MODE S_IRWXU
81
#define FILE_MODE S_IWRITE
85
#define MAX_TMP_BUF_LEN 1024
87
#define MAX_ADD_RULES 50 // update c_config_display.ink
89
//-------------------------------------------------------------------------
91
//-------------------------------------------------------------------------
93
typedef int (*WebHttpHandler) (WebHttpContext * whc, const char *file);
95
//-------------------------------------------------------------------------
97
//-------------------------------------------------------------------------
99
// only allow access to specific files on the autoconf port
100
static InkHashTable *g_autoconf_allow_ht = 0;
102
static InkHashTable *g_submit_bindings_ht = 0;
103
static InkHashTable *g_file_bindings_ht = 0;
104
static InkHashTable *g_extn_bindings_ht = 0;
106
InkHashTable *g_display_config_ht = 0;
108
//-------------------------------------------------------------------------
110
//-------------------------------------------------------------------------
112
void spawn_script(WebHttpContext * whc, char *script, char **args);
114
//-------------------------------------------------------------------------
115
// record_version_valid
116
//-------------------------------------------------------------------------
119
record_version_valid(char *record_version)
121
int old_version, old_pid, cur_version;
122
// coverity[secure_coding]
123
if (sscanf(record_version, "%d:%d", &old_pid, &old_version) == 2 && old_version >= 0) {
124
cur_version = RecGetRecordUpdateCount(RECT_CONFIG);
125
//fix me --> lmgmt->record_data->pid
126
// TODO: need to check the PID ??
127
// if (cur_version != old_version || lmgmt->record_data->pid != old_pid) {
128
if (cur_version != old_version) {
129
// we are out of date since the version number has been incremented
135
// bad format, return false to be safe
139
//-------------------------------------------------------------------------
141
//-------------------------------------------------------------------------
144
set_record_value(WebHttpContext * whc, const char *rec, const char *value)
157
// INKqa11771: exec script that associates with a record
158
record = xstrdup(rec);
159
if ((script = strchr(record, ':'))) {
163
// FIXME: If someone else has already added a NOTE or WARN, then we
164
// won't be able to add anymore. This is desired for
165
// handle_submit_update, but going forward, we'll need a more
166
// general mechanism.
168
varValue.setFromName(record);
169
if (varValue.compareFromString(value) == false) {
170
if (recordValidityCheck(record, value)) {
171
if (recordRestartCheck(record)) {
172
ink_hash_table_insert(whc->submit_note_ht, record, NULL);
173
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_NOTE)) {
174
HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_RESTART_REQUIRED);
175
HtmlRndrBr(whc->submit_note);
177
whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
179
varSetFromStr(record, value);
183
const char *args[MAX_ARGS + 1];
184
for (int i = 0; i < MAX_ARGS; i++)
186
script_path = WebHttpAddDocRoot_Xmalloc(whc, script);
187
args[0] = script_path;
189
processSpawn(&args[0], NULL, NULL, NULL, false, false);
194
ink_hash_table_insert(whc->submit_warn_ht, record, NULL);
195
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
196
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
197
HtmlRndrBr(whc->submit_warn);
199
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
206
//-------------------------------------------------------------------------
208
//-------------------------------------------------------------------------
211
set_config_file(WebHttpContext * whc, char *file_version, char *file_contents, char *file_checksum)
219
char frecord[MAX_VAR_LENGTH + 1];
220
char fname[MAX_VAL_LENGTH + 1];
221
char checksum[MAX_CHECKSUM_LENGTH + 1];
224
// coverity[secure_coding]
225
if (sscanf(file_version, "%d:%s", &fversion, frecord) == 2) {
226
if (varStrFromName(frecord, fname, MAX_VAL_LENGTH)) {
227
if (configFiles->getRollbackObj(fname, &rb)) {
228
// INKqa12198: remove ^M (CR) from each line in file_contents
229
convertHtmlToUnix(file_contents);
230
file_size = strlen(file_contents);
231
tb = NEW(new textBuffer(file_size + 1));
232
tb->copyFrom(file_contents, file_size); //orig
234
// calculate checksum - skip file update if match checksum
235
fileCheckSum(tb->bufPtr(), tb->spaceUsed(), checksum, sizeof(checksum));
236
if (strcmp(file_checksum, checksum) != 0) {
237
if (rb->updateVersion(tb, fversion) != OK_ROLLBACK) {
240
// put note if file update required restart
241
if (recordRestartCheck(frecord)) {
242
ink_hash_table_insert(whc->submit_note_ht, frecord, NULL);
243
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_NOTE)) {
244
HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_RESTART_REQUIRED);
245
HtmlRndrBr(whc->submit_note);
247
whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
257
//-------------------------------------------------------------------------
259
//-------------------------------------------------------------------------
265
// This function is used for constructing a command line from a CGI
266
// scripting program because Windows doesn't know how to execute a
267
// script. For example, instead of executing "blacklist.cgi", we need
268
// to tell Windows to execute "perl.exe blacklist.cgi".
271
adjustCmdLine(char *cmdLine, int cmdline_len, const char *cgiFullPath)
274
char *interpreter = NULL;
276
FILE *f = fopen(cgiFullPath, "r");
278
if (fgets(line, 1024, f) != NULL) {
279
int n = strlen(line);
280
if (n > 2 && strncmp(line, "#!", 2) == 0 && line[n - 1] == '\n') {
282
interpreter = line + 2;
289
snprintf(cmdLine, cmdline_len, "\"%s\" \"%s\"", interpreter, cgiFullPath);
291
ink_strncpy(cmdLine, cgiFullPath, cmdline_len);
299
spawn_cgi(WebHttpContext * whc, const char *cgi_path, char **args, bool nowait, bool run_as_root)
303
const char *query_string;
304
textBuffer query_string_tb(MAX_TMP_BUF_LEN);
306
char content_length_buffer[10];
308
bool success = false;
309
const char *a[MAX_ARGS + 2];
312
httpMessage *request = whc->request;
313
textBuffer *replyMsg = whc->response_bdy;
314
httpResponse *answerHdr = whc->response_hdr;
316
// check if file exists
317
if (stat(cgi_path, &info) < 0) {
318
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
319
answerHdr->setStatus(STATUS_NOT_FOUND);
320
return WEB_HTTP_ERR_REQUEST_ERROR;
322
// initialize arguments
323
for (i = 0; i < MAX_ARGS + 2; i++)
326
for (i = 1; i < MAX_ARGS + 1 && args && args[i - 1]; i++)
329
// initialize environment
330
if (request->getContentType() != NULL) {
331
env.setVar("CONTENT_TYPE", request->getContentType());
333
if (request->getMethod() == METHOD_POST) {
334
env.setVar("REQUEST_METHOD", "POST");
335
query_string = request->getBody();
337
} else if (request->getMethod() == METHOD_GET) {
338
env.setVar("REQUEST_METHOD", "GET");
339
query_string = request->getQuery();
342
answerHdr->setStatus(STATUS_NOT_IMPLEMENTED);
343
WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
344
return WEB_HTTP_ERR_REQUEST_ERROR;;
346
if (query_string != NULL) {
348
// use getConLen() to handle binary
349
qlen = request->getConLen();
351
qlen = strlen(query_string);
352
snprintf(content_length_buffer, sizeof(content_length_buffer), "%d", qlen);
353
env.setVar("CONTENT_LENGTH", content_length_buffer);
354
env.setVar("QUERY_STRING", query_string);
356
query_string_tb.copyFrom(query_string, qlen);
359
if (processSpawn(&a[0], &env, &query_string_tb, replyMsg, nowait, run_as_root) != 0) {
360
mgmt_elog(stderr, "[spawn_cgi] Unable to fork child process\n");
361
WebHttpSetErrorResponse(whc, STATUS_INTERNAL_SERVER_ERROR);
362
answerHdr->setStatus(STATUS_INTERNAL_SERVER_ERROR);
370
char cmdLine[PATH_MAX * 2 + 6];
373
SECURITY_ATTRIBUTES saAttr;
374
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
375
saAttr.bInheritHandle = TRUE;
376
saAttr.lpSecurityDescriptor = NULL;
379
HANDLE hChildStdinR = NULL;
380
HANDLE hChildStdinW = NULL;
382
CreatePipe(&hChildStdinR, &hChildStdinW, &saAttr, 0);
384
// Dup to NULL and set inheritable to FALSE so that
385
// it won't be inherited by the child process
386
DuplicateHandle(GetCurrentProcess(), hChildStdinW, GetCurrentProcess(), NULL, 0, FALSE, DUPLICATE_SAME_ACCESS);
389
HANDLE hChildStdoutR = NULL;
390
HANDLE hChildStdoutW = NULL;
392
CreatePipe(&hChildStdoutR, &hChildStdoutW, &saAttr, 0);
394
// Dup to NULL and set inheritable to FALSE so that
395
// it won't be inherited by the child process
396
DuplicateHandle(GetCurrentProcess(), hChildStdoutR, GetCurrentProcess(), NULL, 0, FALSE, DUPLICATE_SAME_ACCESS);
399
PROCESS_INFORMATION procInfo;
400
ZeroMemory((PVOID) & suInfo, sizeof(suInfo));
402
// hide the new console window from the user
403
suInfo.cb = sizeof(STARTUPINFO);
404
suInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
405
suInfo.wShowWindow = SW_HIDE;
406
suInfo.hStdInput = hChildStdinR;
407
suInfo.hStdOutput = hChildStdoutW;
408
suInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
410
adjustCmdLine(cmdLine, sizeof(cmdLine), cgi_path);
412
if (CreateProcess(NULL, cmdLine, NULL, // FIX THIS: process security attributes
413
NULL, // FIX THIS: thread security attributes
414
TRUE, // make handles inheritable
415
0, // FIX THIS: specify a priority
416
env.toString(), ts_base_dir, // make script run from TSBase
417
&suInfo, &procInfo) == FALSE) {
419
mgmt_elog(stderr, "[spawn_cgi] CreateProcess error: %s\n", ink_last_err());
420
WebHttpSetErrorResponse(whc, STATUS_INTERNAL_SERVER_ERROR);
421
answerHdr->setStatus(STATUS_INTERNAL_SERVER_ERROR);
425
CloseHandle(hChildStdinR);
426
if (request->getMethod() == METHOD_POST && query_string != NULL) {
427
WriteFile(hChildStdinW, query_string, qlen, &nbytes, NULL);
429
CloseHandle(hChildStdinW);
431
CloseHandle(hChildStdoutW);
432
while (ReadFile(hChildStdoutR, buffer, 1024, &nbytes, NULL) == TRUE) {
436
replyMsg->copyFrom(buffer, nbytes);
438
CloseHandle(hChildStdoutR);
444
// was this a plugin callout?
445
if (whc->request_state & WEB_HTTP_STATE_PLUGIN) {
446
// notify server plugin to update its config
447
if (success == true && query_string != NULL) {
448
char *plugin_name = new char[qlen];
449
const char *tmp = strstr(query_string, "INK_PLUGIN_NAME=");
451
tmp += strlen("INK_PLUGIN_NAME=");
452
for (i = 0; *tmp != '&' && *tmp != '\0'; tmp++) {
453
plugin_name[i++] = *tmp;
455
plugin_name[i] = '\0';
456
substituteUnsafeChars(plugin_name);
457
lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, plugin_name);
463
return WEB_HTTP_ERR_OKAY;
466
//-------------------------------------------------------------------------
468
//-------------------------------------------------------------------------
471
handle_cgi_extn(WebHttpContext * whc, const char *file)
476
whc->response_hdr->setCachable(0);
477
whc->response_hdr->setStatus(STATUS_OK);
478
whc->response_hdr->setContentType(TEXT_HTML);
479
cgi_path = WebHttpAddDocRoot_Xmalloc(whc, whc->request->getFile());
480
err = spawn_cgi(whc, cgi_path, NULL, false, false);
485
//-------------------------------------------------------------------------
487
//-------------------------------------------------------------------------
490
handle_ink_extn(WebHttpContext * whc, const char *file)
493
if ((err = WebHttpRender(whc, file)) == WEB_HTTP_ERR_OKAY) {
494
whc->response_hdr->setStatus(STATUS_OK);
495
whc->response_hdr->setLength(whc->response_bdy->spaceUsed());
496
whc->response_hdr->setContentType(TEXT_HTML);
501
//-------------------------------------------------------------------------
503
//-------------------------------------------------------------------------
506
handle_chart(WebHttpContext * whc, const char *file)
509
//-----------------------------------------------------------------------
510
// FIXME: HARD-CODED HTML HELL!!!
511
//-----------------------------------------------------------------------
513
// Note that chart.cgi is a special case so it can not be handled
514
// like our other submit_bindings; the browswer can access the cgi
515
// either by a GET/query or by a POST/body combo.
517
int err = WEB_HTTP_ERR_OKAY;
519
httpMessage *request = whc->request;
520
textBuffer *replyMsg = whc->response_bdy;
521
httpResponse *answerHdr = whc->response_hdr;
522
InkHashTable *post_data_ht, *params;
524
char *varName = NULL;
526
char tmpVal[MAX_VAL_LENGTH];
527
bool postForm = true;
528
bool clusterGraph = false;
531
static const char dimensions[] = "width=\"1600\" height=\"1200\"";
532
static const char multiGraph[] = "Inktomi Real-time Graphing";
534
const int totalNumGraphs = 10;
536
char *theGraphs[totalNumGraphs];
537
const char *theGraphNames[totalNumGraphs];
538
const char *graphNames[] = {
539
"Document Hit Rate", "Bandwidth Savings", "Cache Percent Free",
540
"Open Server Connections", "Open Client Connections",
541
"Cache Transfers In Progress", "Client Throughput",
542
"Transactions Per Second", "Host Database Hit Rate",
543
"DNS Lookups Per Second"
546
static const char str1[] = "<html>\n" "<title>";
547
static const char str1_5[] =
548
"</title>\n" "<body><b> No variable(s) were selected for graphing. </b></body>\n" "</html>\n";
549
static const char str2[] =
551
"<body bgcolor=\"#C0C0C0\" onResize=\"resize()\" onLoad=\"resize()\" "
552
" topmargin=\"0\" leftmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">\n"
553
"<SCRIPT LANGUAGE=\"JavaScript\">\n"
554
" function myFunc(page, winName) {\n"
555
" window.open(page, winName, \"width=850,height=435,status,resizable=yes\");\n"
557
" function resize() {\n"
558
" var w_newWidth,w_newHeight;\n"
559
" var w_maxWidth=1600,w_maxHeight=1200;\n"
560
" if (navigator.appName.indexOf(\"Microsoft\") != -1)\n"
562
" w_newWidth=document.body.clientWidth;\n"
563
" w_newHeight=document.body.clientHeight;\n"
565
" var netscapeScrollWidth=15;\n"
566
" w_newWidth=window.innerWidth-netscapeScrollWidth;\n"
567
" w_newHeight=window.innerHeight-netscapeScrollWidth;\n"
569
" if (w_newWidth>w_maxWidth)\n"
570
" w_newWidth=w_maxWidth;\n"
571
" if (w_newHeight>w_maxHeight)\n"
572
" w_newHeight=w_maxHeight;\n"
573
" document.ink_chart.resizeFrame(w_newWidth,w_newHeight);\n"
574
" window.scroll(0,0);\n" " }\n" " window.onResize = resize;\n" " window.onLoad = resize;\n"
576
" function closeTheBrowser() {\n"
579
" function SnapshotAlert() {\n"
580
" window.alert(\"Snapshot is currently not supported on SSL connection.\");\n" " }\n"
583
"<applet NAME=\"ink_chart\" CODE=\"InktomiCharter.class\" " " ARCHIVE=\"/charting/InkChart.jar\" MAYSCRIPT ";
584
static const char str3[] = ">\n<param name=ServerName value=\"";
585
static const char str3_2[] = "\">\n<param name=ServerPort value=\"";
586
static const char str3_3[] = "\">\n<param name=ServerWebPort value=\"";
587
static const char str3_4[] = "\">\n<param name=Graphs value=\"";
588
static const char str3_5[] = "\">\n<param name=StatNames value=\"";
589
static const char str3_6[] = "\">\n<param name=SSL value=\"";
590
static const char str4[] = "\">\n</applet>\n</body>\n</html>\n";
592
static const int str1Len = strlen(str1);
593
static const int str1_5Len = strlen(str1_5);
594
static const int str2Len = strlen(str2);
595
static const int str3Len = strlen(str3);
596
static const int str3_2Len = strlen(str3_2);
597
static const int str3_3Len = strlen(str3_3);
598
static const int str3_4Len = strlen(str3_4);
599
static const int str3_5Len = strlen(str3_5);
600
static const int str3_6Len = strlen(str3_6);
601
static const int str4Len = strlen(str4);
603
// The graph Generator is a POST form, while the cluster graphs are
604
// GET forms. If we get nothing, assume that we have a postForm.
605
post_data_ht = processFormSubmission(request->getBody());
606
if (post_data_ht == NULL) {
608
params = whc->query_data_ht;
609
// If we still didn't get anything, there is nothing to be had
610
if (params == NULL) {
611
err = WEB_HTTP_ERR_REQUEST_ERROR;
615
params = post_data_ht;
618
if (postForm == false) {
619
// We are trying to generate a cluster graph for a node variable
620
int ink_hash_lookup_result = ink_hash_table_lookup(params, "cluster", (void **) &varName);
621
if (!ink_hash_lookup_result || varName == NULL) {
622
mgmt_log(stderr, "Invalid Graph Submission No graph will be generated\n");
623
err = WEB_HTTP_ERR_REQUEST_ERROR;
628
for (int i = 0; i < totalNumGraphs; i++) {
629
if (ink_hash_table_lookup(params, graphNames[i], (void **) &varName)) {
630
theGraphs[numGraphs] = (char *) varName;
631
theGraphNames[numGraphs] = graphNames[i];
635
clusterGraph = false;
638
varNameLen = varName ? strlen(varName) : 0;
641
replyMsg->copyFrom(str1, str1Len);
642
if (clusterGraph == true && varName) {
643
replyMsg->copyFrom(varName, varNameLen);
645
replyMsg->copyFrom(multiGraph, strlen(multiGraph));
646
if (numGraphs == 0) {
647
replyMsg->copyFrom(str1_5, str1_5Len);
648
answerHdr->setStatus(STATUS_OK);
652
replyMsg->copyFrom(str2, str2Len);
653
replyMsg->copyFrom(dimensions, strlen(dimensions));
655
replyMsg->copyFrom(str3, str3Len);
656
varStrFromName("proxy.node.hostname_FQ", tmpVal, MAX_VAL_LENGTH);
657
replyMsg->copyFrom(tmpVal, strlen(tmpVal));
659
replyMsg->copyFrom(str3_2, str3_2Len);
660
varStrFromName("proxy.config.admin.overseer_port", tmpVal, MAX_VAL_LENGTH);
661
replyMsg->copyFrom(tmpVal, strlen(tmpVal));
663
replyMsg->copyFrom(str3_3, str3_3Len);
664
varStrFromName("proxy.config.admin.web_interface_port", tmpVal, MAX_VAL_LENGTH);
665
replyMsg->copyFrom(tmpVal, strlen(tmpVal));
667
replyMsg->copyFrom(str3_4, str3_4Len);
668
if (clusterGraph == true) {
669
replyMsg->copyFrom("CLUSTER", 7);
671
snprintf(numGraphStr, sizeof(numGraphStr), "%d", numGraphs);
672
replyMsg->copyFrom(numGraphStr, strlen(numGraphStr));
675
replyMsg->copyFrom(str3_5, str3_5Len);
676
if (clusterGraph == true) {
677
replyMsg->copyFrom(varName, varNameLen);
679
for (int j = 1; j < numGraphs; j++) {
680
replyMsg->copyFrom(theGraphs[j], strlen(theGraphs[j]));
681
replyMsg->copyFrom(",", 1);
682
replyMsg->copyFrom(theGraphNames[j], strlen(theGraphNames[j]));
684
replyMsg->copyFrom(",", 1);
686
replyMsg->copyFrom(theGraphs[0], strlen(theGraphs[0]));
687
replyMsg->copyFrom(",", 1);
688
replyMsg->copyFrom(theGraphNames[0], strlen(theGraphNames[0]));
691
replyMsg->copyFrom(str3_6, str3_6Len);
692
if (whc->server_state & WEB_HTTP_SERVER_STATE_SSL_ENABLED) {
693
replyMsg->copyFrom("enabled", strlen("enabled"));
695
replyMsg->copyFrom("disabled", strlen("disabled"));
698
replyMsg->copyFrom(str4, str4Len);
699
answerHdr->setLength(strlen(replyMsg->bufPtr()));
703
ink_hash_table_destroy_and_xfree_values(post_data_ht);
709
//-------------------------------------------------------------------------
710
// handle_record_info
712
// Warning!!! This is really hacky since we should not be directly
713
// accessing the librecords data structures. Just do this here
714
// tempoarily until we can have something better.
715
//-------------------------------------------------------------------------
717
#include "P_RecCore.h"
719
#define LINE_SIZE 512
721
#define NULL_STR "NULL"
728
handle_config_files(WebHttpContext * whc, const char *file)
731
return WebHttpRender(whc, HTML_FILE_ALL_CONFIG);
735
handle_debug_logs(WebHttpContext * whc, const char *file)
738
return WebHttpRender(whc, HTML_VIEW_DEBUG_LOGS_FILE);
741
//-------------------------------------------------------------------------
743
//-------------------------------------------------------------------------
746
handle_synthetic(WebHttpContext * whc, const char *file)
751
whc->response_hdr->setContentType(TEXT_PLAIN);
752
whc->response_hdr->setStatus(STATUS_OK);
755
for (int i = 0; i < 26; i++) {
759
for (int j = 0; j < 60; j++) {
760
whc->response_bdy->copyFrom(buffer, 27);
762
return WEB_HTTP_ERR_OKAY;
765
//-------------------------------------------------------------------------
766
// handle_submit_alarm
767
//-------------------------------------------------------------------------
770
handle_submit_alarm(WebHttpContext * whc, const char *file)
773
resolveAlarm(whc->post_data_ht);
774
whc->top_level_render_file = xstrdup(HTML_ALARM_FILE);
775
return handle_ink_extn(whc, HTML_ALARM_FILE);
778
//-------------------------------------------------------------------------
779
// handle_submit_mgmt_auth
780
//-------------------------------------------------------------------------
782
// set_admin_passwd (sub-function)
784
set_admin_passwd(WebHttpContext * whc)
787
char *admin_orig_epasswd;
788
char *admin_old_passwd;
789
char *admin_old_epasswd;
790
char *admin_new_passwd;
791
char *admin_new_passwd_retype;
792
char *admin_new_epasswd;
797
if (!ink_hash_table_lookup(whc->post_data_ht, "admin_old_passwd", (void **) &admin_old_passwd))
798
admin_old_passwd = NULL;
799
if (!ink_hash_table_lookup(whc->post_data_ht, "admin_new_passwd", (void **) &admin_new_passwd))
800
admin_new_passwd = NULL;
801
if (!ink_hash_table_lookup(whc->post_data_ht, "admin_new_passwd_retype", (void **) &admin_new_passwd_retype))
802
admin_new_passwd_retype = NULL;
804
if ((admin_old_passwd != NULL) || (admin_new_passwd != NULL) || (admin_new_passwd_retype != NULL)) {
806
if (admin_old_passwd == NULL)
807
admin_old_passwd = empty_str;
808
if (admin_new_passwd == NULL)
809
admin_new_passwd = empty_str;
810
if (admin_new_passwd_retype == NULL)
811
admin_new_passwd_retype = empty_str;
813
admin_orig_epasswd = (char *) alloca(INK_ENCRYPT_PASSWD_LEN + 1);
814
varStrFromName("proxy.config.admin.admin_password", admin_orig_epasswd, INK_ENCRYPT_PASSWD_LEN + 1);
816
// INKqa12084: do not encrypt password if empty_str
817
if (strcmp(admin_old_passwd, empty_str) == 0) {
818
admin_old_epasswd = xstrdup(empty_str);
820
INKEncryptPassword(admin_old_passwd, &admin_old_epasswd);
823
if (strncmp(admin_old_epasswd, admin_orig_epasswd, INK_ENCRYPT_PASSWD_LEN) == 0) {
824
if (strcmp(admin_new_passwd, admin_new_passwd_retype) == 0) {
825
// INKqa12084: do not encrypt password if empty_str
826
if (strcmp(admin_new_passwd, empty_str) == 0) {
827
admin_new_epasswd = xstrdup(empty_str);
829
INKEncryptPassword(admin_new_passwd, &admin_new_epasswd);
832
set_record_value(whc, "proxy.config.admin.admin_password", admin_new_epasswd);
833
xfree(admin_new_epasswd);
834
whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
835
HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_NEW_ADMIN_PASSWD_SET);
836
HtmlRndrBr(whc->submit_note);
838
ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.admin.admin_password", NULL);
839
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
840
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_PASSWD_MISTYPE);
841
HtmlRndrBr(whc->submit_warn);
844
ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.admin.admin_password", NULL);
845
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
846
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_OLD_PASSWD_INCORRECT);
847
HtmlRndrBr(whc->submit_warn);
849
xfree(admin_old_epasswd);
855
handle_submit_mgmt_auth(WebHttpContext * whc, const char *file)
858
bool recs_out_of_date;
861
char *record_version;
862
char *submit_from_page;
863
char *aa_session_id, *aa_user_count;
864
char *aa_user, *aa_access, *aa_delete;
865
char *aa_new_user, *aa_new_passwd, *aa_new_passwd_retype, *aa_new_access;
866
char *aa_new_epasswd;
867
char admin_user[MAX_VAL_LENGTH + 1];
868
int user, user_count;
870
INKAdminAccessEle *ele;
871
INKActionNeedT action_need;
881
// initialize pointers we may assign memeory to
882
aa_new_epasswd = NULL;
884
// check for submit_from_page
885
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
886
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
887
whc->top_level_render_file = xstrdup(submit_from_page);
889
submit_from_page = NULL;
893
if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel))
896
// check for record_version
897
recs_out_of_date = true;
898
if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
899
recs_out_of_date = !record_version_valid(record_version);
900
ink_hash_table_delete(whc->post_data_ht, "record_version");
901
xfree(record_version);
903
if (recs_out_of_date)
906
// proxy.config.admin.basic_auth
907
if (ink_hash_table_lookup(whc->post_data_ht, "proxy.config.admin.basic_auth", (void **) &value))
908
set_record_value(whc, "proxy.config.admin.basic_auth", value);
910
// proxy.config.admin.admin_user
911
if (ink_hash_table_lookup(whc->post_data_ht, "proxy.config.admin.admin_user", (void **) &value))
912
set_record_value(whc, "proxy.config.admin.admin_user", value);
914
// proxy.config.admin.admin_password (call sub-function)
915
set_admin_passwd(whc);
917
// grab our session_id and user_count
918
if (ink_hash_table_lookup(whc->post_data_ht, "session_id", (void **) &aa_session_id)) {
919
if (!ink_hash_table_lookup(whc->post_data_ht, "user_count", (void **) &aa_user_count))
920
goto Lunable_to_submit;
921
// find our current session
922
if (WebHttpSessionRetrieve(aa_session_id, (void **) &ctx) != WEB_HTTP_ERR_OKAY)
924
// get new additional-user information
925
if (!ink_hash_table_lookup(whc->post_data_ht, "new_user", (void **) &aa_new_user))
927
if (!ink_hash_table_lookup(whc->post_data_ht, "new_passwd", (void **) &aa_new_passwd))
928
aa_new_passwd = NULL;
929
if (!ink_hash_table_lookup(whc->post_data_ht, "new_passwd_retype", (void **) &aa_new_passwd_retype))
930
aa_new_passwd_retype = NULL;
931
if (!ink_hash_table_lookup(whc->post_data_ht, "new_access", (void **) &aa_new_access))
932
aa_new_access = NULL;
933
// check if the user is trying to add a new additional-user
934
if (aa_new_user != NULL) {
935
// kwt 12.March.2001 check for username length
936
if (strlen(aa_new_user) > WEB_HTTP_AUTH_USER_MAX) {
937
ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
938
ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
939
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
940
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_USERNAME_LENGTH);
941
HtmlRndrBr(whc->submit_warn);
945
if (aa_new_user != NULL) {
946
if (aa_new_passwd == NULL)
947
aa_new_passwd = empty_str;
948
if (aa_new_passwd_retype == NULL)
949
aa_new_passwd_retype = empty_str;
950
if (strcmp(aa_new_passwd, aa_new_passwd_retype) == 0) {
951
// allocating memory on aa_new_epasswd
952
INKEncryptPassword(aa_new_passwd, &aa_new_epasswd);
954
ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
955
ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
956
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
957
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_PASSWD_MISTYPE);
958
HtmlRndrBr(whc->submit_warn);
961
// check if the new_user is the same as the proxy.config.admin.admin_user
962
if (aa_new_user != NULL) {
963
varStrFromName("proxy.config.admin.admin_user", admin_user, MAX_VAL_LENGTH + 1);
964
if (strcmp(aa_new_user, admin_user) == 0) {
965
ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
966
ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
967
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
968
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_USER_DUPLICATE);
969
HtmlRndrBr(whc->submit_warn);
974
// Walk through members and update settings in ctx backwards.
975
// Client submitted values should be in the same order as the ctx
976
// since we originally created this page from the same ctx.
977
// Looping backwards helps so that we can delete elements by
980
user_count = ink_atoi(aa_user_count);
981
for (user = user_count - 1; user >= 0; user--) {
982
snprintf(tmp_a, sizeof(tmp_a), "user:%d", user);
983
snprintf(tmp_b, sizeof(tmp_b), "access:%d", user);
984
if (ink_hash_table_lookup(whc->post_data_ht, tmp_a, (void **) &aa_user) &&
985
ink_hash_table_lookup(whc->post_data_ht, tmp_b, (void **) &aa_access)) {
986
snprintf(tmp_a, sizeof(tmp_a), "delete:%d", user);
987
if (ink_hash_table_lookup(whc->post_data_ht, tmp_a, (void **) &aa_delete)) {
988
INKCfgContextRemoveEleAt(ctx, user);
992
ele = (INKAdminAccessEle *) INKCfgContextGetEleAt(ctx, user);
993
if (strcmp(ele->user, aa_user) != 0) {
994
goto Lunable_to_submit;
996
if (aa_new_user && (strcmp(aa_new_user, aa_user) == 0)) {
997
ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
998
ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
999
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1000
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_USER_DUPLICATE);
1001
HtmlRndrBr(whc->submit_warn);
1004
access_t = (INKAccessT) ink_atoi(aa_access);
1005
if (ele->access != access_t) {
1006
ele->access = access_t;
1010
goto Lunable_to_submit;
1014
if ((aa_new_user != NULL) && (aa_new_epasswd != NULL)) {
1015
ele = INKAdminAccessEleCreate();
1016
ele->user = xstrdup(aa_new_user);
1017
ele->password = xstrdup(aa_new_epasswd);
1018
// FIXME: no access for now, add back later?
1019
//ele->access = aa_new_access ? (INKAccessT)ink_atoi(aa_new_access) : INK_ACCESS_NONE;
1020
ele->access = INK_ACCESS_NONE;
1021
INKCfgContextAppendEle(ctx, (INKCfgEle *) ele);
1025
if (INKCfgContextCommit(ctx, &action_need, NULL) != INK_ERR_OKAY) {
1026
WebHttpSessionDelete(aa_session_id);
1029
INKActionDo(action_need);
1031
WebHttpSessionDelete(aa_session_id);
1033
goto Lunable_to_submit;
1038
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1039
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_OUT_OF_DATE);
1040
HtmlRndrBr(whc->submit_warn);
1044
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1045
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_UNABLE_TO_SUBMIT);
1046
HtmlRndrBr(whc->submit_warn);
1050
if (aa_new_epasswd) {
1051
xfree(aa_new_epasswd);
1053
return WebHttpRender(whc, HTML_MGMT_LOGIN_FILE);
1061
//-------------------------------------------------------------------------
1062
// handle_submit_snapshot
1063
//-------------------------------------------------------------------------
1065
// Doesn't seem to be used.
1066
static int INK_UNUSED
1067
handle_submit_snapshot(WebHttpContext * whc, const char *file)
1069
NOWARN_UNUSED(file);
1071
SnapResult snap_result = SNAP_OK;
1072
char *submit_from_page;
1075
char *snap_location;
1076
char *snap_directory;
1077
char *ftp_server_name;
1078
char *ftp_remote_dir;
1081
char *snapDirFromRecordsConf;
1083
struct stat snapDirStat;
1084
char config_dir[PATH_NAME_MAX];
1087
if (varStrFromName("proxy.config.config_dir", config_dir, PATH_NAME_MAX) == false)
1089
"[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
1091
if ((err = stat(config_dir, &s)) < 0) {
1092
ink_strncpy(config_dir, system_config_directory,sizeof(config_dir));
1093
if ((err = stat(config_dir, &s)) < 0) {
1094
mgmt_elog("[WebHttp::handle_submit_snapshot] unable to stat() directory '%s': %d %d, %s\n",
1095
config_dir, err, errno, strerror(errno));
1096
mgmt_fatal("[WebHttp::handle_submit_snapshot] please set config path via command line '-path <path>' or 'proxy.config.config_dir' \n");
1099
// check for submit_from_page
1100
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
1101
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
1102
whc->top_level_render_file = xstrdup(submit_from_page);
1104
submit_from_page = NULL;
1109
// FIXME: button names here are going to be hard to
1110
// internationalize. we should put the button names into the
1114
if (ink_hash_table_lookup(whc->post_data_ht, "snap_action", (void **) &snap_action)) {
1115
// take the snapshot action
1116
if (strcmp(snap_action, " Change ") == 0) {
1117
if (ink_hash_table_lookup(whc->post_data_ht, "Change Directory", (void **) &snap_directory)) {
1118
if (snap_directory == NULL) {
1119
mgmt_log(stderr, "Change Directory not specified.");
1121
ink_assert(RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf)
1123
if (snapDirFromRecordsConf == NULL) {
1124
// coverity[size_is_strlen]
1125
snapDirFromRecordsConf = new char[strlen("snapshots")];
1126
snprintf(snapDirFromRecordsConf, strlen("snapshots"), "%s", "snapshots");
1127
ink_assert(RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf)
1129
ink_assert(RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf)
1131
RecSetRecordString("proxy.config.snapshot_dir", (RecString) snapDirFromRecordsConf);
1133
if (strcasecmp(snapDirFromRecordsConf, snap_directory)) {
1134
RecSetRecordString("proxy.config.snapshot_dir", snap_directory);
1135
// Create a directory for the snap shot
1136
if (snap_directory[0] != '/') {
1137
// coverity[alloc_fn][var_assign]
1138
char *snap_dir_cpy = strdup(snap_directory);
1141
// coverity[noescape]
1142
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1143
snap_directory = new char[newLen];
1144
ink_assert(snap_directory != NULL);
1145
// coverity[noescape]
1146
snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1147
//snap_directory = newPathString(config_dir, snap_dir_cpy);
1148
RecSetRecordString("proxy.config.snapshot_dir", snap_dir_cpy);
1153
if (stat(snap_directory, &snapDirStat)) {
1154
SimpleTokenizer snapDirPathTok(snap_directory, '/');
1155
int dirDepth = snapDirPathTok.getNumTokensRemaining();
1157
for (int i = 1; i <= dirDepth; i++) {
1158
if (snap_directory[0] == '/') {
1161
const char *tok = snapDirPathTok.getNext(i);
1163
newLen = strlen(tok) + 2;
1164
absoluteDir = new char[newLen];
1165
ink_assert(absoluteDir != NULL);
1166
snprintf(absoluteDir, newLen, "/%s", tok);
1168
if (mkdir(absoluteDir, DIR_MODE) < 0) {
1169
perror("Absolute snapPath Directory creation:");
1171
delete[]absoluteDir;
1173
const char *tok = snapDirPathTok.getNext(i);
1174
// These weren't used, so moved. /leif
1176
//char* absoluteDir;
1177
//const char *config_dir = lmgmt->record_data ->readString("proxy.config.config_dir", &found);
1179
//newLen = strlen(tok) + strlen(config_dir) + 2;
1180
//absoluteDir = new char[newLen];
1181
//ink_assert(absoluteDir != NULL);
1182
//sprintf(absoluteDir, "%s%s%s",config_dir, DIR_SEP, tok);
1184
//if ((ret_val = mkdir(absoluteDir, DIR_MODE)) < 0) {
1185
//perror("Absolute snapPath Directory creation:");
1187
//delete [] absoluteDir;
1188
if (mkdir(tok, DIR_MODE) < 0) {
1189
perror("Relative snapPath Directory creation:");
1192
snapDirPathTok.setString(snap_directory);
1195
//if(snap_directory[0] == '/') {
1196
//lmgmt->record_data ->setString("proxy.config.snapshot_dir", snap_directory);
1199
//char* relativeDir;
1200
//const char *config_dir = lmgmt->record_data ->readString("proxy.config.config_dir", &found);
1202
//newLen = strlen(snap_directory) + strlen(config_dir) + 2;
1203
//relativeDir = new char[newLen];
1204
//ink_assert(relativeDir != NULL);
1205
//sprintf(relativeDir, "%s%s%s",config_dir, DIR_SEP, snap_directory);
1206
//lmgmt->record_data ->setString("proxy.config.snapshot_dir", relativeDir);
1212
} else if (strcmp(snap_action, " Take ") == 0) {
1213
if (ink_hash_table_lookup(whc->post_data_ht, "new_snap", (void **) &snap_name)) {
1214
if (snap_name == NULL) {
1215
mgmt_log(stderr, "Snapshots name on disk not specified.");
1218
if (ink_hash_table_lookup(whc->post_data_ht, "Snapshots Location", (void **) &snap_location)) {
1219
// coverity[var_compare_op]
1220
if (snap_location == NULL) {
1221
mgmt_log(stderr, "Snapshots Location not specified.");
1224
if (snap_location && strcmp(snap_location, "OnDisk") == 0) {
1225
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snap_directory);
1227
if (snap_directory[0] != '/') {
1228
// coverity[alloc_fn][var_assign]
1229
char *snap_dir_cpy = strdup(snap_directory);
1232
// coverity[noescape]
1233
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1234
snap_directory = new char[newLen];
1235
ink_assert(snap_directory != NULL);
1236
// coverity[noescape]
1237
snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1241
snap_result = configFiles->takeSnap(snap_name, snap_directory);
1242
} else if (!(strcmp(snap_location, "FTPServerUpload")) || !(strcmp(snap_location, "FTPServerDownload"))) {
1243
if (ink_hash_table_lookup(whc->post_data_ht, "FTPServerName", (void **) &ftp_server_name)) {
1244
if (ftp_server_name == NULL) {
1245
mgmt_log(stderr, "FTPServerName not specified.");
1248
if (ink_hash_table_lookup(whc->post_data_ht, "FTPRemoteDir", (void **) &ftp_remote_dir)) {
1249
if (ftp_server_name == NULL) {
1250
mgmt_log(stderr, "FTPRemoteDir not specified.");
1253
if (ink_hash_table_lookup(whc->post_data_ht, "FTPLogin", (void **) &ftp_login)) {
1254
if (ftp_login == NULL) {
1255
mgmt_log(stderr, "FTPLogin not specified.");
1258
if (ink_hash_table_lookup(whc->post_data_ht, "FTPPassword", (void **) &ftp_password)) {
1259
if (ftp_password == NULL) {
1260
mgmt_log(stderr, "FTPPassword not specified.");
1263
if (!(strcmp(snap_location, "FTPServerUpload")) && snap_name) {
1264
int localDirLength, remoteDirLength;
1266
char *ftp_remote_dir_name;
1268
localDirLength = strlen(snap_name) + strlen("/tmp") + 2;
1269
remoteDirLength = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
1271
newStr = new char[localDirLength];
1272
ink_assert(newStr != NULL);
1273
ftp_remote_dir_name = new char[remoteDirLength];
1274
ink_assert(ftp_remote_dir_name != NULL);
1275
snprintf(newStr, localDirLength, "/tmp%s%s", DIR_SEP, snap_name);
1276
snprintf(ftp_remote_dir_name, remoteDirLength, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
1277
snap_result = configFiles->takeSnap(snap_name, "/tmp");
1278
INKMgmtFtp("put", ftp_server_name, ftp_login, ftp_password, newStr, ftp_remote_dir_name, NULL);
1280
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1281
ink_release_assert(found);
1283
if (snapDirFromRecordsConf[0] != '/') {
1284
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1287
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + strlen(snap_name) + 3;
1288
snapDirFromRecordsConf = new char[newLen];
1289
ink_assert(snapDirFromRecordsConf != NULL);
1290
snprintf(snapDirFromRecordsConf, newLen, "%s%s%s%s%s", config_dir, DIR_SEP, snap_dir_cpy, DIR_SEP,
1296
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1299
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + strlen(snap_name) + 3;
1300
snapDirFromRecordsConf = new char[newLen];
1301
ink_assert(snapDirFromRecordsConf != NULL);
1302
snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", snap_dir_cpy, DIR_SEP, snap_name);
1308
//const char *config_dir = lmgmt->record_data ->readString("proxy.config.config_dir", &found);
1310
newLen = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
1311
newStr = new char[newLen];
1312
ink_assert(newStr != NULL);
1313
snprintf(newStr, newLen, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
1315
if (mkdir(snapDirFromRecordsConf, DIR_MODE) < 0) {
1316
mgmt_log(stderr, "Cannot create %s\n", snapDirFromRecordsConf);
1318
INKMgmtFtp("get", ftp_server_name, ftp_login, ftp_password, snapDirFromRecordsConf, newStr, NULL);
1321
} else if (!(strcmp(snap_location, "FloppySave")) || !(strcmp(snap_location, "FloppyCopy"))) {
1322
char *floppyMountPoint;
1323
if (ink_hash_table_lookup(whc->post_data_ht, "FloppyDrive", (void **) &floppyMountPoint)) {
1324
//coverity [var_compare_op]
1325
if (floppyMountPoint == NULL)
1326
mgmt_log(stderr, "FloppyMountPoint not found.");
1328
if (snap_location && strcmp(snap_location, "FloppySave") == 0) {
1329
snap_result = configFiles->takeSnap(snap_name, floppyMountPoint);
1332
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1333
snprintf(args, sizeof(args), "cp -fr %s/%s %s", floppyMountPoint, snap_name, snapDirFromRecordsConf);
1334
const char *argv[] = { args,
1337
processSpawn(argv, NULL, NULL, NULL, false, false);
1340
mgmt_log(stderr, "Illegal value for snapshot location.");
1342
// take a snapshot for the current configuration files
1343
} else if (strcmp(snap_action, " Restore ") == 0) {
1344
// restore the selected snapshot
1345
if (ink_hash_table_lookup(whc->post_data_ht, "snap_name", (void **) &snap_name)) {
1346
if (strcmp(snap_name, "- select a snapshot -")) {
1347
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1348
ink_release_assert(found);
1349
if (snapDirFromRecordsConf[0] != '/') {
1350
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1351
ink_assert(snap_dir_cpy);
1354
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1355
snapDirFromRecordsConf = new char[newLen];
1356
ink_assert(snapDirFromRecordsConf != NULL);
1357
snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1361
snap_result = configFiles->restoreSnap(snap_name, snapDirFromRecordsConf);
1364
} else if (strcmp(snap_action, " Delete ") == 0) {
1365
// delete the selected snapshot
1366
if (ink_hash_table_lookup(whc->post_data_ht, "snap_name", (void **) &snap_name)) {
1367
if (strcmp(snap_name, "- select a snapshot -")) {
1368
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1369
ink_release_assert(found);
1370
if (snapDirFromRecordsConf[0] != '/') {
1371
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1372
ink_assert(snap_dir_cpy);
1375
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1376
snapDirFromRecordsConf = new char[newLen];
1377
ink_assert(snapDirFromRecordsConf != NULL);
1378
snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1382
snap_result = configFiles->removeSnap(snap_name, snapDirFromRecordsConf);
1387
mgmt_log(stderr, "Unknown action is specified.");
1395
if (snap_result != SNAP_OK) {
1396
// FIXME: show alarm error for snapshot!
1399
if (submit_from_page) {
1400
err = WebHttpRender(whc, submit_from_page);
1401
xfree(submit_from_page);
1403
err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
1409
//-------------------------------------------------------------------------
1410
// handle_submit_snapshot_to_filesystem
1411
//-------------------------------------------------------------------------
1414
handle_submit_snapshot_to_filesystem(WebHttpContext * whc, const char *file)
1416
NOWARN_UNUSED(file);
1418
SnapResult snap_result = SNAP_OK;
1419
char *submit_from_page;
1422
char *snap_directory;
1423
char *snapDirFromRecordsConf;
1426
struct stat snapDirStat;
1427
char config_dir[256];
1428
char *record_version;
1429
ExpandingArray snap_list(25, true);
1432
if (varStrFromName("proxy.config.config_dir", config_dir, 256) == false)
1434
"[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
1436
// check for submit_from_page
1437
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
1438
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
1439
whc->top_level_render_file = xstrdup(submit_from_page);
1441
submit_from_page = NULL;
1445
if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
1446
whc->post_data_ht = NULL;
1449
// check for record_version
1450
if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
1451
// TODO: Check return value?
1452
record_version_valid(record_version);
1453
ink_hash_table_delete(whc->post_data_ht, "record_version");
1454
xfree(record_version);
1457
if (ink_hash_table_lookup(whc->post_data_ht, "Change Directory", (void **) &snap_directory)) {
1458
if (snap_directory == NULL) {
1459
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_filesystem] Change Directory not specified.");
1460
ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
1461
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1462
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
1463
HtmlRndrBr(whc->submit_warn);
1465
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1469
const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._-/\\";
1471
const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._-/\\ ";
1473
int snapnameLength = strlen(snap_directory);
1474
int validnameLength = strspn(snap_directory, valid_chars);
1475
if (snapnameLength != validnameLength) {
1476
ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
1477
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1478
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
1479
HtmlRndrBr(whc->submit_warn);
1481
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1485
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1486
ink_release_assert(found);
1487
if (snapDirFromRecordsConf == NULL) {
1488
snapDirFromRecordsConf = new char[strlen("snapshots")];
1489
snprintf(snapDirFromRecordsConf, strlen("snapshots"), "%s", "snapshots");
1490
RecSetRecordString("proxy.config.snapshot_dir", snapDirFromRecordsConf);
1492
if (strcasecmp(snapDirFromRecordsConf, snap_directory)) {
1493
RecSetRecordString("proxy.config.snapshot_dir", snapDirFromRecordsConf);
1494
// Create a directory for the snap shot
1495
if (snap_directory[0] != '/') {
1496
char *snap_dir_cpy = strdup(snap_directory);
1499
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1500
snap_directory = new char[newLen];
1501
ink_assert(snap_directory != NULL);
1502
snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1503
RecSetRecordString("proxy.config.snapshot_dir", snap_dir_cpy);
1507
if (!stat(snap_directory, &snapDirStat)) {
1508
bool write_possible = true;
1509
bool read_possible = true;
1511
if (snapDirStat.st_uid != getuid()) {
1512
if (snapDirStat.st_gid != getgid()) {
1513
if (!(snapDirStat.st_mode & 00002)) {
1514
write_possible = false;
1516
write_possible = true;
1519
if (!(snapDirStat.st_mode & 00020)) {
1520
write_possible = false;
1522
write_possible = true;
1527
if (snapDirStat.st_uid != getuid()) {
1528
if (snapDirStat.st_gid != getgid()) {
1529
if (!(snapDirStat.st_mode & 00004)) {
1530
read_possible = false;
1532
read_possible = true;
1535
if (!(snapDirStat.st_mode & 00040)) {
1536
read_possible = false;
1538
read_possible = true;
1544
attr = GetFileAttributes(snap_directory);
1545
if ((attr & FILE_ATTRIBUTE_READONLY) != 0) { // read only dir
1546
write_possible = false;
1547
read_possible = false;
1549
write_possible = true;
1550
read_possible = true;
1553
if (!write_possible) {
1554
if (!read_possible) {
1555
ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
1556
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1557
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_PERMISSION_DENIED);
1558
HtmlRndrBr(whc->submit_warn);
1560
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1561
RecSetRecordString("proxy.config.snapshot_dir", snap_directory);
1567
if (stat(snap_directory, &snapDirStat)) {
1568
SimpleTokenizer snapDirPathTok(snap_directory, '/');
1569
int dirDepth = snapDirPathTok.getNumTokensRemaining();
1571
for (int i = 1; i <= dirDepth; i++) {
1572
if (snap_directory[0] == '/') {
1575
const char *tok = snapDirPathTok.getNext(i);
1577
newLen = strlen(tok) + 2;
1578
absoluteDir = new char[newLen];
1579
ink_assert(absoluteDir != NULL);
1580
snprintf(absoluteDir, newLen, "/%s", tok);
1583
if (mkdir(absoluteDir, DIR_MODE) < 0) {
1585
if (mkdir(absoluteDir) < 0) {
1587
perror("[WebHttp::handle_submit_snapshot_to_filesystem] Absolute snapPath Directory creation:");
1589
delete[]absoluteDir;
1591
const char *tok = snapDirPathTok.getNext(i);
1593
if (mkdir(tok, DIR_MODE) < 0) {
1595
if (mkdir(tok) < 0) {
1597
perror("[WebHttp::handle_submit_snapshot_to_filesystem] Relative snapPath Directory creation:");
1600
snapDirPathTok.setString(snap_directory);
1607
if (ink_hash_table_lookup(whc->post_data_ht, "SnapshotName", (void **) &snap_name)) {
1608
if (snap_name != NULL) {
1610
const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._";
1612
const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._ ";
1614
int snapnameLength = strlen(snap_name);
1615
int validnameLength = strspn(snap_name, valid_chars);
1616
if (snapnameLength != validnameLength) {
1617
ink_hash_table_insert(whc->submit_warn_ht, "SnapShotName", NULL);
1618
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1619
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
1620
HtmlRndrBr(whc->submit_warn);
1622
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1627
snap_result = configFiles->WalkSnaps(&snap_list);
1628
if (snap_result == SNAP_OK) {
1629
num_snaps = snap_list.getNumEntries();
1630
if (num_snaps > 0) {
1631
for (int i = 0; i < num_snaps; i++)
1632
if (!strcmp((char *) snap_list[i], snap_name)) {
1633
if (ink_hash_table_lookup(whc->post_data_ht, "Delete Snapshot", (void **) &snap_action)) {
1634
if (ink_hash_table_lookup(whc->post_data_ht, "restore_delete_name", (void **) &snap_action)) {
1635
if (snap_action != NULL) {
1636
if (!strcmp(snap_name, snap_action))
1641
ink_hash_table_insert(whc->submit_warn_ht, "SnapShotName", NULL);
1642
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1643
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_DUPLICATE_ENTRY);
1644
HtmlRndrBr(whc->submit_warn);
1646
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1650
ink_hash_table_delete(whc->post_data_ht, "SnapshotName");
1653
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snap_directory);
1654
ink_release_assert(found);
1656
if (snap_directory[0] != '/') {
1657
char *snap_dir_cpy = strdup(snap_directory);
1660
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1661
snap_directory = new char[newLen];
1662
ink_assert(snap_directory != NULL);
1663
snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1667
snap_result = configFiles->takeSnap(snap_name, snap_directory);
1668
if (snap_result == 3) {
1669
ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
1670
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1671
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_PERMISSION_DENIED);
1672
HtmlRndrBr(whc->submit_warn);
1674
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1675
RecSetRecordString("proxy.config.snapshot_dir", snap_directory);
1681
if (ink_hash_table_lookup(whc->post_data_ht, "Restore Snapshot", (void **) &snap_action)) {
1682
if (ink_hash_table_lookup(whc->post_data_ht, "restore_delete_name", (void **) &snap_name)) {
1683
if (strcmp(snap_name, "- select a snapshot -")) {
1684
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1685
ink_release_assert(found);
1686
if (snapDirFromRecordsConf[0] != '/') {
1687
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1688
ink_assert(snap_dir_cpy);
1690
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1691
snapDirFromRecordsConf = new char[newLen];
1692
ink_assert(snapDirFromRecordsConf != NULL);
1693
snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1697
snap_result = configFiles->restoreSnap(snap_name, snapDirFromRecordsConf);
1698
if (snap_result < 0) {
1699
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_filesystem] Restore snapshot failed");
1706
if (ink_hash_table_lookup(whc->post_data_ht, "Delete Snapshot", (void **) &snap_action)) {
1707
if (ink_hash_table_lookup(whc->post_data_ht, "restore_delete_name", (void **) &snap_name)) {
1708
if (strcmp(snap_name, "- select a snapshot -")) {
1709
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1710
ink_release_assert(found);
1711
if (snapDirFromRecordsConf[0] != '/') {
1712
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1713
ink_assert(snap_dir_cpy);
1715
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1716
snapDirFromRecordsConf = new char[newLen];
1717
ink_assert(snapDirFromRecordsConf != NULL);
1718
snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1722
snap_result = configFiles->removeSnap(snap_name, snapDirFromRecordsConf);
1723
if (snap_result < 0) {
1724
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_filesystem] Remove snapshot failed");
1733
if (submit_from_page) {
1734
err = WebHttpRender(whc, submit_from_page);
1735
xfree(submit_from_page);
1737
err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
1748
//-------------------------------------------------------------------------
1749
// handle_submit_snapshot_to_ftpserver
1750
//-------------------------------------------------------------------------
1753
handle_submit_snapshot_to_ftpserver(WebHttpContext * whc, const char *file)
1755
NOWARN_UNUSED(file);
1757
char *submit_from_page;
1759
char *ftp_server_name;
1760
char *ftp_remote_dir;
1763
char *snapDirFromRecordsConf;
1764
char *tempDirFromRecordsConf;
1767
// Doesn't seem to be used.
1768
//struct stat snapDirStat;
1769
char config_dir[256];
1770
char *record_version;
1771
ExpandingArray snap_list(25, true);
1773
if (varStrFromName("proxy.config.config_dir", config_dir, 256) == false)
1775
"[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
1777
// check for submit_from_page
1778
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
1779
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
1780
whc->top_level_render_file = xstrdup(submit_from_page);
1782
submit_from_page = NULL;
1786
if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
1787
whc->post_data_ht = NULL;
1790
// check for record_version
1791
if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
1792
// TODO: Check return value?
1793
record_version_valid(record_version);
1794
ink_hash_table_delete(whc->post_data_ht, "record_version");
1795
xfree(record_version);
1799
if (ink_hash_table_lookup(whc->post_data_ht, "FTPServerName", (void **) &ftp_server_name)) {
1800
if (ftp_server_name == NULL) {
1801
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPServerName not specified.");
1802
ink_hash_table_insert(whc->submit_warn_ht, "FTPServerNameError", NULL);
1803
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1804
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
1805
HtmlRndrBr(whc->submit_warn);
1807
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1812
if (ink_hash_table_lookup(whc->post_data_ht, "FTPUserName", (void **) &ftp_login)) {
1813
if (ftp_login == NULL) {
1814
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPlogin not specified.");
1815
ink_hash_table_insert(whc->submit_warn_ht, "FTPUserNameError", NULL);
1816
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1817
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
1818
HtmlRndrBr(whc->submit_warn);
1820
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1825
if (ink_hash_table_lookup(whc->post_data_ht, "FTPPassword", (void **) &ftp_password)) {
1826
if (ftp_password == NULL) {
1827
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPpassword not specified.");
1828
ink_hash_table_insert(whc->submit_warn_ht, "FTPPasswordError", NULL);
1829
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1830
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
1831
HtmlRndrBr(whc->submit_warn);
1833
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1838
if (ink_hash_table_lookup(whc->post_data_ht, "FTPRemoteDir", (void **) &ftp_remote_dir)) {
1839
if (ftp_remote_dir == NULL) {
1840
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPremote_dir not specified.");
1841
ink_hash_table_insert(whc->submit_warn_ht, "FTPRemoteDirError", NULL);
1842
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1843
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
1844
HtmlRndrBr(whc->submit_warn);
1846
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1850
if (ink_hash_table_lookup(whc->post_data_ht, "ftp_select", (void **) &snap_name)) {
1851
if (strcmp(snap_name, "- select a snapshot -")) {
1852
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
1855
snapDirFromRecordsConf = lmgmt->record_data ->readString("proxy.config.snapshot_dir", &found);
1858
if(snapDirFromRecordsConf[0] != '/') {
1859
const char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1862
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + strlen(snap_name) + 3;
1863
snapDirFromRecordsConf = new char[newLen];
1864
ink_assert(snapDirFromRecordsConf != NULL);
1865
sprintf(snapDirFromRecordsConf, "%s%s%s%s%s", config_dir, DIR_SEP, snap_dir_cpy, DIR_SEP, snap_name);
1867
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
1868
snap_dir = new char[newLen];
1869
ink_assert(snap_dir != NULL);
1870
sprintf(snap_dir, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
1873
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
1876
newLen = strlen(snap_dir_cpy) + strlen(snap_name) + 2;
1877
snapDirFromRecordsConf = new char[newLen];
1878
ink_assert(snapDirFromRecordsConf != NULL);
1879
sprintf(snapDirFromRecordsConf, "%s%s%s", snap_dir_cpy, DIR_SEP, snap_name);
1881
snap_dir = snap_dir_cpy;
1884
found = (RecGetRecordString_Xmalloc("proxy.config.temp_dir", &tempDirFromRecordsConf)
1887
ink_release_assert(found);
1892
newLen = strlen(tempDirFromRecordsConf) + strlen(snap_name) + 2;
1893
char *tmp_ftp_snap = new char[newLen];
1894
ink_assert(tmp_ftp_snap != NULL);
1895
snprintf(tmp_ftp_snap, newLen, "%s%s%s", tempDirFromRecordsConf, DIR_SEP, snap_name);
1897
newLen = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
1898
newStr = new char[newLen];
1899
ink_assert(newStr != NULL);
1900
snprintf(newStr, newLen, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
1902
if (mkdir(tmp_ftp_snap, DIR_MODE) < 0) {
1903
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] Cannot create %s\n", tmp_ftp_snap);
1905
char ftpOutput[4096];
1906
INKMgmtFtp("get", ftp_server_name, ftp_login, ftp_password, tmp_ftp_snap, newStr, ftpOutput);
1907
if (!strncmp(ftpOutput, "ERROR:", 6)) {
1908
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTP get failed : %s", ftpOutput);
1911
// TODO: Check return values?
1912
configFiles->restoreSnap(snap_name, tempDirFromRecordsConf);
1913
configFiles->removeSnap(snap_name, tempDirFromRecordsConf);
1918
if (ink_hash_table_lookup(whc->post_data_ht, "FTPSaveName", (void **) &snap_name)) {
1919
if (snap_name != NULL) {
1920
int localDirLength, remoteDirLength;
1922
char *ftp_remote_dir_name;
1924
localDirLength = strlen(snap_name) + strlen("/tmp") + 2;
1925
remoteDirLength = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
1927
newStr = new char[localDirLength];
1928
ink_assert(newStr != NULL);
1929
ftp_remote_dir_name = new char[remoteDirLength];
1930
ink_assert(ftp_remote_dir_name != NULL);
1931
snprintf(newStr, localDirLength, "/tmp%s%s", DIR_SEP, snap_name);
1932
snprintf(ftp_remote_dir_name, remoteDirLength, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
1933
configFiles->takeSnap(snap_name, "/tmp");
1934
char ftpOutput[4096];
1935
INKMgmtFtp("put", ftp_server_name, ftp_login, ftp_password, newStr, ftp_remote_dir_name, ftpOutput);
1936
if (!strncmp(ftpOutput, "ERROR:", 6)) {
1937
//mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTP put failed : %s", ftpOutput);
1938
fprintf(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTP put failed : %s", ftpOutput);
1939
if (!strncmp(ftpOutput, "ERROR: FTP Put:: permission", 27)) {
1940
ink_hash_table_insert(whc->submit_warn_ht, "FTPRemoteDirError", NULL);
1941
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
1942
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_PERMISSION_DENIED);
1943
HtmlRndrBr(whc->submit_warn);
1945
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
1954
if (submit_from_page) {
1955
err = WebHttpRender(whc, submit_from_page);
1956
xfree(submit_from_page);
1958
err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
1966
//-------------------------------------------------------------------------
1967
// handle_submit_snapshot_to_floppy
1968
//-------------------------------------------------------------------------
1971
handle_submit_snapshot_to_floppy(WebHttpContext * whc, const char *file)
1973
NOWARN_UNUSED(file);
1975
SnapResult snap_result = SNAP_OK;
1976
char *submit_from_page;
1977
char *snapDirFromRecordsConf;
1979
char *floppy_drive_mount_point;
1980
char *floppy_selected_snap_name;
1981
char *floppy_snap_name;
1983
//struct stat snapDirStat;
1984
char config_dir[256];
1985
char *record_version;
1986
char *UnmountFloppy;
1988
const char *linkFile;
1989
ExpandingArray snap_list(25, true);
1991
if (varStrFromName("proxy.config.config_dir", config_dir, 256) == false)
1993
"[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
1995
// check for submit_from_page
1996
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
1997
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
1998
whc->top_level_render_file = xstrdup(submit_from_page);
2000
submit_from_page = NULL;
2004
if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
2005
whc->post_data_ht = NULL;
2008
// check for record_version
2009
if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
2010
// TODO: Check return value?
2011
record_version_valid(record_version);
2012
ink_hash_table_delete(whc->post_data_ht, "record_version");
2013
xfree(record_version);
2020
if (ink_hash_table_lookup(whc->post_data_ht, "Unmount Floppy", (void **) &UnmountFloppy)) {
2021
if (UnmountFloppy != NULL) {
2024
if (strcmp(UnmountFloppy, "Unmount Floppy") == 0) {
2025
char unmountPath[1024];
2027
if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
2028
if (floppy_drive_mount_point != NULL)
2029
snprintf(unmountPath, sizeof(unmountPath), "/bin/umount %s", floppy_drive_mount_point);
2031
NOWARN_UNUSED_RETURN(system("sync;sync;sync"));
2032
linkFile = "/configure/c_snapshot_floppy.ink";
2033
ink_hash_table_insert(whc->submit_warn_ht, "CouldnotUnmount", NULL);
2034
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2035
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_FLOPPY_UNMOUNT_ERR);
2036
HtmlRndrBr(whc->submit_warn);
2038
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2039
if (submit_from_page)
2040
xfree(submit_from_page);
2041
submit_from_page = xstrdup(linkFile);
2046
if ((pid = fork()) < 0) {
2048
} else if (pid == 0) {
2049
old_euid = getuid();
2052
ret = system(unmountPath);
2053
setreuid(old_euid, old_euid);
2060
linkFile = "/configure/c_snapshot_floppy.ink";
2061
ink_hash_table_insert(whc->submit_warn_ht, "CouldnotUnmount", NULL);
2062
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2063
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_FLOPPY_UNMOUNT_ERR);
2064
HtmlRndrBr(whc->submit_warn);
2066
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2067
if (submit_from_page)
2068
xfree(submit_from_page);
2069
submit_from_page = xstrdup(linkFile);
2072
linkFile = "/configure/c_basic.ink";
2076
char *link = WebHttpGetLink_Xmalloc(linkFile);
2077
whc->response_hdr->setRefreshURL(link);
2080
whc->response_hdr->setRefresh(0);
2081
if (submit_from_page)
2082
xfree(submit_from_page);
2083
submit_from_page = xstrdup(linkFile);
2088
if (ink_hash_table_lookup(whc->post_data_ht, "floppy_select", (void **) &floppy_selected_snap_name)) {
2089
if (floppy_selected_snap_name != NULL) {
2090
if (strcmp(floppy_selected_snap_name, "- select a snapshot -")) {
2091
if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
2093
RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
2095
if (snapDirFromRecordsConf[0] != '/') {
2096
// coverity[alloc_fn][var_assign]
2097
char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
2100
// coverity[noescape]
2101
newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
2102
snapDirFromRecordsConf = new char[newLen];
2103
ink_assert(snapDirFromRecordsConf != NULL);
2104
// coverity[noescape]
2105
snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
2109
if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
2110
snap_result = configFiles->restoreSnap(floppy_selected_snap_name, floppy_drive_mount_point);
2111
if (snap_result < 0) {
2112
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_floppy] Restore snap failed");
2122
if (ink_hash_table_lookup(whc->post_data_ht, "FloppySnapName", (void **) &floppy_snap_name)) {
2123
if (floppy_snap_name != NULL) {
2124
if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
2126
struct dirent *dirEntry;
2129
// Doesn't seem to be used.
2130
//struct stat fileInfo;
2131
//struct stat records_config_fileInfo;
2132
//fileEntry* fileListEntry;
2134
dir = opendir(floppy_drive_mount_point);
2137
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_floppy] Unable to open %s directory: %s\n",
2138
floppy_drive_mount_point, strerror(errno));
2141
// The fun of Solaris - readdir_r requires a buffer passed into it
2142
// The man page says this obscene expression gives us the proper
2144
dirEntry = (struct dirent *) xmalloc(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1);
2145
struct dirent *result;
2146
while (readdir_r(dir, dirEntry, &result) == 0) {
2149
fileName = dirEntry->d_name;
2150
if (!strcmp(fileName, floppy_snap_name)) {
2151
ink_hash_table_insert(whc->submit_warn_ht, "FloppyError", NULL);
2152
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2153
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_DUPLICATE_ENTRY);
2154
HtmlRndrBr(whc->submit_warn);
2156
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2167
snap_result = configFiles->takeSnap(floppy_snap_name, floppy_drive_mount_point);
2168
if (snap_result < 0) {
2169
mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_floppy] Take snap failed");
2170
} else if (snap_result == 6) {
2172
ink_hash_table_insert(whc->submit_warn_ht, "FloppySaveFailed", NULL);
2173
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2174
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_FLOPPY_NO_SPACE);
2175
HtmlRndrBr(whc->submit_warn);
2177
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2180
ink_hash_table_delete(whc->post_data_ht, "FloppySnapName");
2187
if (submit_from_page) {
2188
err = WebHttpRender(whc, submit_from_page);
2189
xfree(submit_from_page);
2191
err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
2198
//-------------------------------------------------------------------------
2199
// handle_submit_inspector
2200
//-------------------------------------------------------------------------
2202
handle_submit_inspector(WebHttpContext * whc, const char *file)
2204
NOWARN_UNUSED(file);
2206
char *submit_from_page;
2211
// check for submit_from_page
2212
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
2213
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
2214
whc->top_level_render_file = xstrdup(submit_from_page);
2216
submit_from_page = NULL;
2219
// FIXME: button names here are going to be hard to
2220
// internationalize. we should put the button names into the
2223
// handle URL Regex operation
2224
if (ink_hash_table_lookup(whc->post_data_ht, "regex_op", (void **) ®ex_action)) {
2225
if (strcmp(regex_action, "Lookup") == 0) {
2226
// handle regex lookup
2227
if (ink_hash_table_lookup(whc->post_data_ht, "regex", (void **) ®ex)) {
2228
if ((err = INKLookupFromCacheUrlRegex(regex, &list)) == INK_ERR_OKAY) {
2229
whc->cache_query_result = list;
2232
} else if (strcmp(regex_action, "Delete") == 0) {
2233
// handle regex delete
2234
if (ink_hash_table_lookup(whc->post_data_ht, "regex", (void **) ®ex)) {
2235
if ((err = INKDeleteFromCacheUrlRegex(regex, &list)) == INK_ERR_OKAY) {
2236
whc->cache_query_result = list;
2239
} else if (strcmp(regex_action, "Invalidate") == 0) {
2240
// handle regex invalidate
2241
if (ink_hash_table_lookup(whc->post_data_ht, "regex", (void **) ®ex)) {
2242
if ((err = INKInvalidateFromCacheUrlRegex(regex, &list)) == INK_ERR_OKAY) {
2243
whc->cache_query_result = list;
2248
// Error: unknown action
2250
mgmt_log(stderr, "Unknown action is specified.");
2253
if (err != INK_ERR_OKAY) {
2254
// FIXME: show alarm error for cache inspector!
2257
if (submit_from_page) {
2258
err = WebHttpRender(whc, submit_from_page);
2259
xfree(submit_from_page);
2261
err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
2267
//-------------------------------------------------------------------------
2268
// handle_submit_inspector_display
2269
//-------------------------------------------------------------------------
2272
handle_submit_inspector_display(WebHttpContext * whc, const char *file)
2274
NOWARN_UNUSED(file);
2280
InkHashTable *query_ht;
2282
// processFormSubmission will substituteUnsafeChars()
2283
ht = whc->query_data_ht;
2284
// extract some basic info for easier access later
2285
if (ink_hash_table_lookup(ht, "url_op", (void **) &url_action)) {
2286
// handle URL operation
2287
if (strcmp(url_action, "Lookup") == 0) {
2288
// handle url lookup
2289
if (ink_hash_table_lookup(ht, "url", (void **) &url)) {
2290
if ((err = INKLookupFromCacheUrl(url, &buf)) == INK_ERR_OKAY) {
2291
whc->cache_query_result = buf;
2294
} else if (strcmp(url_action, "Delete") == 0) {
2295
// the url that cache_inspector takes has to be w/o substituteUnsafeChars()
2296
if ((query_ht = processFormSubmission_noSubstitute((char *) (whc->request->getQuery()))) != NULL) {
2297
if (ink_hash_table_lookup(query_ht, "url", (void **) &url)) {
2298
// handle url delete
2299
if ((err = INKDeleteFromCacheUrl(url, &buf)) == INK_ERR_OKAY) {
2300
whc->cache_query_result = buf;
2303
ink_hash_table_destroy_and_xfree_values(query_ht);
2307
// Error: unknown action
2309
mgmt_log(stderr, "Unknown action is specified.");
2312
err = WebHttpRender(whc, HTML_INSPECTOR_DISPLAY_FILE);
2316
//-------------------------------------------------------------------------
2317
// handle_submit_view_logs
2318
//-------------------------------------------------------------------------
2320
handle_submit_view_logs(WebHttpContext * whc, const char *file)
2322
NOWARN_UNUSED(file);
2324
char *submit_from_page;
2327
char *action = NULL;
2328
char *logfile = NULL;
2329
char tmp[MAX_TMP_BUF_LEN + 1];
2331
time_t file_date_gmt;
2333
// check for submit_from_page
2334
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
2335
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
2336
whc->top_level_render_file = xstrdup(submit_from_page);
2338
submit_from_page = NULL;
2341
#if !defined(_WIN32)
2343
// handle remove/save file action before rendering
2344
if (!ink_hash_table_lookup(whc->post_data_ht, "logfile", (void **) &logfile))
2346
if (!ink_hash_table_lookup(whc->post_data_ht, "action", (void **) &action))
2348
if (!logfile || !action)
2350
if (strcmp(logfile, "default") == 0)
2353
if (strcmp(action, "view_last") == 0) {
2354
if (!ink_hash_table_lookup(whc->post_data_ht, "nlines", (void **) &nlines))
2356
// 'nlines' entry is missing
2357
if (nlines == NULL) {
2358
ink_hash_table_insert(whc->submit_warn_ht, "view_last", NULL);
2362
} else if (strcmp(action, "view_subset") == 0) {
2363
if (!ink_hash_table_lookup(whc->post_data_ht, "substring", (void **) &substring))
2365
// 'substring' entry is missing
2366
if (substring == NULL) {
2367
ink_hash_table_insert(whc->submit_warn_ht, "view_subset", NULL);
2371
} else if (strcmp(action, "remove") == 0) {
2373
snprintf(tmp, MAX_TMP_BUF_LEN, "/bin/rm -f %s", logfile);
2375
Debug("web2", "[handle_submit_view_logs] unable to execute \"%s\"", tmp);
2376
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2377
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2378
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_LOG_REMOVE_FAILED);
2379
HtmlRndrBr(whc->submit_warn);
2382
// done removal - remove from post_data_ht not to display previous action
2383
ink_hash_table_delete(whc->post_data_ht, "action");
2384
ink_hash_table_delete(whc->post_data_ht, "logfile");
2388
} else if (strcmp(action, "save") == 0) {
2390
if ((h_file = WebFileOpenR(logfile)) == WEB_HANDLE_INVALID) {
2391
Debug("web2", "[handle_submit_view_logs] unable to open logfile \"%s\"", logfile);
2393
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2394
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2395
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_LOG_SAVE_FAILED);
2396
HtmlRndrBr(whc->submit_warn);
2399
file_size = WebFileGetSize(h_file);
2400
file_date_gmt = WebFileGetDateGmt(h_file);
2401
whc->response_hdr->setStatus(STATUS_OK);
2402
whc->response_hdr->setLength(file_size);
2403
whc->response_hdr->setLastMod(file_date_gmt);
2404
whc->response_hdr->setContentType(TEXT_UNKNOWN);
2405
while (whc->response_bdy->rawReadFromFile(h_file) > 0);
2406
WebFileClose(h_file);
2407
return WEB_HTTP_ERR_OKAY;
2410
Debug("web2", "[handle_submit_view_logs] unknown action '%s' on '%s'", action, logfile);
2417
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2418
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2419
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
2420
HtmlRndrBr(whc->submit_warn);
2424
// nothing needs to be done, just start rendering
2425
if (submit_from_page) {
2426
err = WebHttpRender(whc, submit_from_page);
2427
xfree(submit_from_page);
2429
err = WebHttpRender(whc, HTML_DEFAULT_MONITOR_FILE);
2434
//-------------------------------------------------------------------------
2435
// handle_submit_update
2436
//-------------------------------------------------------------------------
2439
handle_submit_update(WebHttpContext * whc, const char *file)
2441
NOWARN_UNUSED(file);
2443
char *submit_from_page;
2444
bool recs_out_of_date;
2445
bool file_out_of_date;
2446
char *record_version;
2448
char *file_contents;
2449
char *file_checksum;
2453
char *clear_cluster;
2454
bool use_ssl_updated;
2456
// check for submit_from_page
2457
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
2458
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
2459
whc->top_level_render_file = xstrdup(submit_from_page);
2461
submit_from_page = NULL;
2465
if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
2468
// check for restart
2469
if (ink_hash_table_lookup(whc->post_data_ht, "restart", (void **) &cancel)) {
2471
char *link = WebHttpGetLink_Xmalloc(HTML_DEFAULT_CONFIGURE_FILE);
2472
whc->response_hdr->setRefreshURL(link);
2475
lmgmt->ccom->sendClusterMessage(CLUSTER_MSG_SHUTDOWN_MANAGER);
2476
whc->response_hdr->setRefresh(15);
2477
if (submit_from_page)
2478
xfree(submit_from_page);
2479
submit_from_page = xstrdup("/restart.ink");
2482
// check for clear statistics
2483
if (ink_hash_table_lookup(whc->post_data_ht, "clear_stats", (void **) &clear)) {
2484
lmgmt->clearStats();
2487
// check for cluster clear statistics
2488
if (ink_hash_table_lookup(whc->post_data_ht, "clear_cluster_stats", (void **) &clear_cluster)) {
2489
lmgmt->clearStats();
2490
lmgmt->ccom->sendClusterMessage(CLUSTER_MSG_CLEAR_STATS);
2493
// check for roll_logs
2494
if (ink_hash_table_lookup(whc->post_data_ht, "roll_logs", (void **) &cancel)) {
2495
lmgmt->rollLogFiles();
2499
if (ink_hash_table_lookup(whc->post_data_ht, "apply", (void **) &apply)) {
2500
ink_hash_table_delete(whc->post_data_ht, "apply");
2503
// check for record_version
2504
recs_out_of_date = true;
2505
if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
2506
// TODO: Check return value?
2507
recs_out_of_date = !record_version_valid(record_version);
2508
ink_hash_table_delete(whc->post_data_ht, "record_version");
2509
xfree(record_version);
2511
// check for a file_version and file_contents
2512
file_out_of_date = false;
2513
if (ink_hash_table_lookup(whc->post_data_ht, "file_version", (void **) &file_version)) {
2514
if (ink_hash_table_lookup(whc->post_data_ht, "file_contents", (void **) &file_contents)) {
2515
file_out_of_date = true;
2516
if (ink_hash_table_lookup(whc->post_data_ht, "file_checksum", (void **) &file_checksum)) {
2517
if (!file_version) {
2518
file_version = (char *) xstrdup("");
2520
if (!file_contents) {
2521
file_contents = (char *) xstrdup("");
2523
if (!file_checksum) {
2524
file_checksum = (char *) xstrdup("");
2526
file_out_of_date = !set_config_file(whc, file_version, file_contents, file_checksum);
2527
ink_hash_table_delete(whc->post_data_ht, "file_checksum");
2529
xfree(file_checksum);
2531
ink_hash_table_delete(whc->post_data_ht, "file_contents");
2533
xfree(file_contents);
2535
ink_hash_table_delete(whc->post_data_ht, "file_version");
2537
xfree(file_version);
2539
// everything else should be records. if the user modifies the
2540
// 'proxy.config.admin.use_ssl' variable, we'll have to redirect
2541
// them appropriately.
2542
use_ssl_updated = false;
2543
if (!recs_out_of_date) {
2544
InkHashTableIteratorState htis;
2545
InkHashTableEntry *hte;
2548
for (hte = ink_hash_table_iterator_first(whc->post_data_ht, &htis);
2549
hte != NULL; hte = ink_hash_table_iterator_next(whc->post_data_ht, &htis)) {
2550
record = (char *) ink_hash_table_entry_key(whc->post_data_ht, hte);
2551
value = (char *) ink_hash_table_entry_value(whc->post_data_ht, hte);
2552
// check for ssl redirect
2553
if (strcasecmp(record, "proxy.config.admin.use_ssl") == 0) {
2554
char use_ssl_value[MAX_VAL_LENGTH]; // The value of the current variable
2555
if ((varStrFromName(record, use_ssl_value, MAX_VAL_LENGTH)) && (ink_atoi(value) != ink_atoi(use_ssl_value))
2557
use_ssl_updated = true;
2562
// warn if out of date submission
2563
if (recs_out_of_date || file_out_of_date) {
2564
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_OUT_OF_DATE);
2565
HtmlRndrBr(whc->submit_warn);
2566
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2569
if (use_ssl_updated) {
2570
if (submit_from_page) {
2571
xfree(submit_from_page);
2573
submit_from_page = xstrdup("/ssl_redirect.ink");
2577
if (submit_from_page && strcmp(submit_from_page, HTML_FEATURE_ON_OFF_FILE) == 0) {
2578
WebHttpTreeRebuildJsTree();
2583
if (submit_from_page) {
2584
err = WebHttpRender(whc, submit_from_page);
2585
xfree(submit_from_page);
2587
err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
2593
//-------------------------------------------------------------------------
2594
// handle_submit_update_config
2595
//-------------------------------------------------------------------------
2596
// This handler is called when submit a post form for Configuration File Editor.
2597
// Uses the hidden tag values to construct and write new config file.
2598
// If the user presses Cancel, then it should also close
2599
// the current window without committing any changes. If hit "Apply", then
2600
// commits the changes before closing editor window.
2601
// Since the Configuration File Editor opens in a separate window,
2602
// each time a user hits "Apply", we need to also update the table listing all
2603
// the config rules on the original tab page from which the File Editor window
2604
// was launched - the orignal page is refreshed regularly in order to keep the
2605
// the values in sync with the Configuration File Editor page (is there a
2606
// better way to do this??)
2607
// The file parameter is not used in this handler because a generic
2608
// c_config_display.ink is used for all files. We determine which file
2609
// is being revised by using the filename tag that's passed in with the
2612
handle_submit_update_config(WebHttpContext * whc, const char *file)
2614
NOWARN_UNUSED(file);
2615
char **rules = NULL;
2616
char name[10]; // "rule#"
2622
int i, numRules = 0;
2623
int err = WEB_HTTP_ERR_OKAY;
2624
char *errBuff = NULL;
2627
if (ink_hash_table_lookup(whc->post_data_ht, "close", (void **) &close)) {
2629
return WEB_HTTP_ERR_OKAY;
2632
if (ink_hash_table_lookup(whc->post_data_ht, "apply", (void **) &apply)) {
2633
ink_hash_table_delete(whc->post_data_ht, "apply");
2636
// This portion of the code handles parsing the hidden tags with all
2637
// the current ruleList information; commits this information as new config file
2639
// get the filename to create the INKCfgContext; do NOT delete the
2640
// HTML_CONFIG_FILE_TAG entry because we need to use the filename
2641
// binding to refresh the page
2642
if (!ink_hash_table_lookup(whc->post_data_ht, HTML_CONFIG_FILE_TAG, (void **) &filename)) {
2643
// ERROR: no config file specified!!
2644
whc->response_hdr->setStatus(STATUS_NOT_FOUND);
2645
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
2649
if (ink_hash_table_lookup(g_display_config_ht, filename, (void **) &type)) {
2652
INKCfgContext ctx = INKCfgContextCreate(type);
2653
if (ctx && (INKCfgContextGet(ctx) == INK_ERR_OKAY)) {
2654
maxRules = INKCfgContextGetCount(ctx) + MAX_ADD_RULES;
2655
INKCfgContextDestroy(ctx);
2658
// read all the rules from the post form into an array of strings
2661
rules = new char *[maxRules];
2662
for (i = 0; i < maxRules; i++) {
2663
memset(name, 0, 10);
2664
snprintf(name, sizeof(name), "rule%d", i);
2666
if (ink_hash_table_lookup(whc->post_data_ht, name, (void **) &(rules[i]))) {
2667
// do not delete entry from table yet
2671
break; // exit because no more valid rules to read
2677
case INK_FNAME_CACHE_OBJ:
2678
err = updateCacheConfig(rules, numRules, &errBuff);
2680
case INK_FNAME_HOSTING:
2681
err = updateHostingConfig(rules, numRules, &errBuff);
2683
case INK_FNAME_ICP_PEER:
2684
err = updateIcpConfig(rules, numRules, &errBuff);
2686
case INK_FNAME_IP_ALLOW:
2687
err = updateIpAllowConfig(rules, numRules, &errBuff);
2689
case INK_FNAME_MGMT_ALLOW:
2690
err = updateMgmtAllowConfig(rules, numRules, &errBuff);
2692
case INK_FNAME_PARENT_PROXY:
2693
err = updateParentConfig(rules, numRules, &errBuff);
2695
case INK_FNAME_PARTITION:
2696
err = updatePartitionConfig(rules, numRules, &errBuff);
2698
case INK_FNAME_REMAP:
2699
err = updateRemapConfig(rules, numRules, &errBuff);
2701
case INK_FNAME_SOCKS:
2702
err = updateSocksConfig(rules, numRules, &errBuff);
2704
case INK_FNAME_SPLIT_DNS:
2705
err = updateSplitDnsConfig(rules, numRules, &errBuff);
2707
case INK_FNAME_UPDATE_URL:
2708
err = updateUpdateConfig(rules, numRules, &errBuff);
2710
case INK_FNAME_VADDRS:
2711
err = updateVaddrsConfig(rules, numRules, &errBuff);
2714
err = WEB_HTTP_ERR_FAIL;
2718
// do not delete the strings in the array because
2719
// the binding still exists in the hashtable, so memory will
2720
// be freed when post_data_ht destroyed
2724
} else { // missing binding from f_xx_config.ink to INKFileNameT
2725
whc->response_hdr->setStatus(STATUS_NOT_FOUND);
2726
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
2730
if (err == WEB_HTTP_ERR_INVALID_CFG_RULE) {
2731
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2732
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_CFG_INVALID_RULE);
2733
HtmlRndrBr(whc->submit_warn);
2736
whc->submit_warn->copyFrom(errBuff, strlen(errBuff));
2739
} else if (err != WEB_HTTP_ERR_OKAY) {
2740
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_CFG_COMMIT_ERROR);
2741
HtmlRndrBr(whc->submit_warn);
2742
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2744
// do not remove and free frecord from post_data_ht because
2745
// the renderer fn will use it to write the hidden tag
2746
if (ink_hash_table_lookup(whc->post_data_ht, "frecord", (void **) &frecord)) {
2747
if (recordRestartCheck(frecord)) {
2748
ink_hash_table_insert(whc->submit_note_ht, frecord, NULL);
2749
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_NOTE)) {
2750
HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_RESTART_REQUIRED_FILE);
2751
HtmlRndrBr(whc->submit_note);
2753
whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
2757
err = WebHttpRender(whc, HTML_CONFIG_DISPLAY_FILE);
2761
mgmt_log("[handle_submit_update_config] Error updating config file");
2762
return WEB_HTTP_ERR_REQUEST_ERROR;
2766
//-------------------------------------------------------------------------
2767
// handle_submit_config_display
2768
//-------------------------------------------------------------------------
2769
// This handler is called when user wants to open the Configuration Editor
2770
// window to edit a config file; so it main purpose is simply to
2771
// render the configurator.ink page
2773
handle_submit_config_display(WebHttpContext * whc, const char *file)
2775
NOWARN_UNUSED(file);
2776
// same HTML_CONFIG_DISPLAY_FILE for all config files
2777
return WebHttpRender(whc, HTML_CONFIG_DISPLAY_FILE);
2781
//-------------------------------------------------------------------------
2782
// network configuration
2783
//-------------------------------------------------------------------------
2787
NICCheck(WebHttpContext * whc, char *updown, char *arg)
2793
if (strcmp(updown, "0") == 0) {
2795
ink_hash_table_insert(whc->submit_warn_ht, arg, NULL);
2796
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2797
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
2798
HtmlRndrBr(whc->submit_warn);
2800
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2806
SetWarning(WebHttpContext * whc, char *arg)
2808
ink_hash_table_insert(whc->submit_warn_ht, arg, NULL);
2809
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
2810
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
2811
HtmlRndrBr(whc->submit_warn);
2813
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
2816
//-------------------------------------------------------------------------
2817
// handle_submit_net_config
2818
//-------------------------------------------------------------------------
2819
// This handler is called when user wants to setup network of the appliance
2822
handle_submit_net_config(WebHttpContext * whc, const char *file)
2824
NOWARN_UNUSED(file);
2826
char *record_version;
2827
char *submit_from_page;
2830
// tmp=fopen("tmp","a");
2831
// fprintf(tmp,"enter submit\n");
2833
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
2834
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
2835
whc->top_level_render_file = xstrdup(submit_from_page);
2837
submit_from_page = NULL;
2840
if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel))
2841
return WebHttpRender(whc, submit_from_page);
2843
// check for record_version
2844
if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
2845
// TODO: Check return value?
2846
record_version_valid(record_version);
2847
ink_hash_table_delete(whc->post_data_ht, "record_version");
2848
xfree(record_version);
2850
// if (recs_out_of_date)
2851
// goto Lout_of_date;
2853
#if defined(linux) || defined(solaris)
2855
InkHashTableIteratorState htis;
2856
InkHashTableEntry *hte;
2859
int hn_change, gw_change, dn_change, dns_change;
2862
char *dns_ip[3], old_value[265], old_hostname[80], old_gw_ip[80];
2863
char nic_name[5][10], *nic[5][6], interface[80], *param;
2864
char *hostname = 0, *gw_ip = 0;
2870
//This will be used as flags to verify whether anything changed by the user
2875
warning = (fail = false);
2876
//FIXNOW - we need to use SysAPI to find the numver of NICs instead of just constant 5
2877
for (i = 0; i < 5; i++) {
2879
ink_strncpy(nic_name[i], "", 1);
2880
for (j = 0; j < 6; j++) {
2886
Config_User_Root(&old_euid);
2887
// Get the values the user entered
2888
for (hte = ink_hash_table_iterator_first(whc->post_data_ht, &htis);
2889
hte != NULL; hte = ink_hash_table_iterator_next(whc->post_data_ht, &htis)) {
2890
key = (char *) ink_hash_table_entry_key(whc->post_data_ht, hte);
2891
value = (char *) ink_hash_table_entry_value(whc->post_data_ht, hte);
2893
// fprintf(stderr,"key=%s, value=%s\n",key,value);
2895
if (strcmp(key, "HOSTNAME") == 0) {
2897
if (!Net_IsValid_Hostname(hostname)) {
2898
SetWarning(whc, key);
2901
if (!Config_GetHostname(old_value, sizeof(old_value))) {
2902
if (hostname != NULL && strcmp(hostname, old_value) != 0) {
2904
ink_strncpy(old_hostname, old_value, sizeof(old_hostname)); //old hostname is used in MGMT API
2906
} else if (hostname != NULL) {
2910
} else if (strcmp(key, "GATEWAY") == 0) {
2912
if (!Net_IsValid_IP(gw_ip)) {
2913
SetWarning(whc, key);
2916
if (!Config_GetDefaultRouter(old_value, sizeof(old_value))) {
2917
if (gw_ip != NULL && strcmp(gw_ip, old_value) != 0) {
2918
ink_strncpy(old_gw_ip, old_value, sizeof(old_gw_ip));
2921
} else if (gw_ip != NULL) {
2925
} else if (strcmp(key, "domain") == 0) {
2927
if (!Config_GetDomain(old_value, sizeof(old_value))) {
2928
if (dn != NULL && strcmp(dn, old_value) != 0) {
2930
} else if (dn == NULL) {
2934
} else if (dn != NULL) {
2937
} else if (strstr(key, "DNS") != NULL) {
2938
no = atoi(key + 3) - 1;
2940
if (!Net_IsValid_IP(dns_ip[no])) {
2941
SetWarning(whc, key);
2944
if (Config_GetDNS_Server(old_value, sizeof(old_value), no)) {
2945
if (dns_ip[no] != NULL && strcmp(dns_ip[no], old_value) != 0) {
2947
} else if (dns_ip[no] == NULL) {
2950
} else if (dns_ip[no] != NULL) {
2954
} else if (strstr(key, "NIC") != NULL) {
2955
ink_strncpy(interface, key + 4, sizeof(interface));
2956
param = strchr(interface, '_');
2959
no = atoi(interface + 3);
2960
ink_strncpy(nic_name[no], interface, sizeof(nic_name[no]));
2962
//No DHCP support any more, hacking way is set it be static always
2963
nic[no][2] = xstrdup("1");
2964
if (strcmp(param, "enabled") == 0) {
2969
if (strcmp(nic[no][0], "0") == 0) {
2970
SetWarning(whc, key);
2974
//FIXNOW - Use SysAPI
2975
Config_GetNIC_Status(interface, old_value, sizeof(old_value));
2976
if (strcmp(old_value, "up") == 0 && strcmp(nic[no][0], "0") == 0) {
2978
} else if (strcmp(old_value, "down") == 0 && strcmp(nic[no][0], "1") == 0) {
2981
} else if (strcmp(param, "ONBOOT") == 0) {
2986
if (strcmp(nic[no][1], "0") == 0) {
2987
SetWarning(whc, key);
2991
//FIXNOW - Use SysAPI
2992
if (!Config_GetNIC_Start(interface, old_value, sizeof(old_value))) {
2993
if (strcmp(nic[no][1], "1") == 0 && strcmp(old_value, "not-onboot") == 0) {
2995
} else if (strcmp(nic[no][1], "0") == 0 && strcmp(old_value, "onboot") == 0) {
3001
} else if (strcmp(param, "BOOTPROTO") == 0) {
3003
//FIXNOW - Use SysAPI
3004
if (!Config_GetNIC_Protocol(interface, old_value, sizeof(old_value))) {
3005
if (strcmp(nic[no][2], "0") == 0 && (strcmp(old_value, "none") == 0 || strcmp(old_value, "static") == 0)) {
3007
} else if (strcmp(nic[no][2], "1") == 0 && strcmp(old_value, "dhcp") == 0) {
3014
//currently, force the protocol to become static if the old one is dhcp
3015
if (strcmp(old_value, "dhcp") == 0) {
3016
// XXX - changed it so we don't change value and instead duplicate the string
3017
nic[no][2] = xstrdup("1");
3020
} else if (strcmp(param, "IPADDR") == 0) {
3022
//FIXNOW - Use SysAPI
3023
if (!Net_IsValid_IP(nic[no][3])) {
3024
SetWarning(whc, key);
3027
//FIXNOW - Use SysAPI
3028
if (!Config_GetNIC_IP(interface, old_value, sizeof(old_value))) {
3029
if (nic[no][3] != NULL && strcmp(nic[no][3], old_value) != 0) {
3032
//For dhcp start, the static IP maybe same with the dhcp value
3035
Config_GetNIC_Protocol(interface, protocol, sizeof(protocol));
3036
if (strcmp(protocol, "dhcp") == 0) {
3040
if (nic[no][3] == NULL) {
3044
} else if (nic[no][3] != NULL) {
3047
} else if (strcmp(param, "NETMASK") == 0) {
3049
//FIXNOW - Use SysAPI
3050
if (!Net_IsValid_IP(nic[no][4])) {
3051
SetWarning(whc, key);
3054
//FIXNOW - Use SysAPI
3055
if (!Config_GetNIC_Netmask(interface, old_value, sizeof(old_value))) {
3056
if (nic[no][4] != NULL && strcmp(nic[no][4], old_value) != 0) {
3059
//For dhcp start, the static netmask maybe same with the dhcp value
3062
Config_GetNIC_Protocol(interface, protocol, sizeof(protocol));
3063
if (strcmp(protocol, "dhcp") == 0) {
3067
if (nic[no][4] == NULL) {
3071
} else if (nic[no][4] != NULL) {
3074
} else if (strcmp(param, "GATEWAY") == 0) {
3076
//FIXNOW - Use SysAPI
3077
if (!Net_IsValid_IP(nic[no][5])) {
3078
SetWarning(whc, key);
3081
//FIXNOW - Use SysAPI
3082
if (!Config_GetNIC_Gateway(interface, old_value, sizeof(old_value))) {
3083
if (nic[no][5] != NULL && strcmp(nic[no][5], old_value) != 0) {
3086
//For dhcp start, the gateway maybe same with the dhcp value
3089
Config_GetNIC_Protocol(interface, protocol, sizeof(protocol));
3090
if (strcmp(protocol, "dhcp") == 0) {
3094
if (nic[no][5] == NULL) {
3098
} else if (nic[no][5] != NULL) {
3104
Config_User_Inktomi(old_euid);
3108
if (Config_SetHostname(hostname) != 0) {
3113
if (Config_SetDefaultRouter(gw_ip) != 0) {
3118
if (Config_SetDomain(dn) != 0) {
3123
ink_strncpy(dns_ips, "", sizeof(dns_ips));
3124
//FIXNOW - do we have no. of dns servers from SysAPI?
3125
for (i = 0; i < 3; i++) {
3126
if (dns_ip[i] != NULL) {
3127
strncat(dns_ips, dns_ip[i], sizeof(dns_ips) - strlen(dns_ips) - 1);
3128
strncat(dns_ips, " ", sizeof(dns_ips) - strlen(dns_ips) - 1);
3132
if (Config_SetDNS_Servers(dns_ips) != 0) {
3136
//FIXNOW - get the no. from SysAPI
3137
for (i = 0; i < 5; i++) {
3138
if (strlen(nic_name[i]) != 0) {
3139
if (nic_change[i]) {
3140
if (nic[i][0] != NULL && strcmp(nic[i][0], "1") == 0) {
3141
char onboot[20], protocol[20];
3142
if (strcmp(nic[i][1], "1") == 0) {
3143
ink_strncpy(onboot, "onboot", sizeof(onboot));
3145
ink_strncpy(onboot, "not-onboot", sizeof(onboot));
3148
if (strcmp(nic[i][2], "1") == 0) {
3149
ink_strncpy(protocol, "static", sizeof(protocol));
3151
ink_strncpy(protocol, "dhcp", sizeof(protocol));
3153
if (Config_SetNIC_Up(nic_name[i], onboot, protocol, nic[i][3], nic[i][4], nic[i][5]) != 0) {
3158
Config_GetNIC_Status(nic_name[i], status, sizeof(status));
3159
if (strcmp(status, "up") == 0) { //NIC is disabled
3160
if (Config_SetNIC_Down(nic_name[i]) != 0) {
3163
} else { //NIC is down&changed, such changes are disallowed.
3164
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
3165
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NETWORK_CONFIG_DISALLOW);
3166
HtmlRndrBr(whc->submit_warn);
3168
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
3175
//FIXME, need a complete fail message system
3177
if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
3178
HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NETWORK_CONFIG_FAIL);
3179
HtmlRndrBr(whc->submit_warn);
3181
whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
3185
if (submit_from_page)
3186
xfree(submit_from_page);
3187
submit_from_page = xstrdup("/rename.ink");
3190
return WebHttpRender(whc, submit_from_page);
3193
//-------------------------------------------------------------------------
3194
// handle_submit_otw_upgrade
3195
//-------------------------------------------------------------------------
3197
handle_submit_otw_upgrade(WebHttpContext * whc, const char *file)
3199
NOWARN_UNUSED(file);
3200
int err = WEB_HTTP_ERR_OKAY;
3203
char *submit_from_page;
3204
char tmp[MAX_TMP_BUF_LEN];
3208
const char *cgi_path;
3210
if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
3211
ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
3212
whc->top_level_render_file = xstrdup(submit_from_page);
3214
submit_from_page = NULL;
3219
if (ink_hash_table_lookup(whc->post_data_ht, "action", (void **) &action)) {
3220
if (strcmp(action, "Cancel") == 0) {
3221
// upgrade cancelled = return to HTML_OTW_UPGRADE_FILE
3222
if (ink_hash_table_lookup(whc->post_data_ht, "working_dir", (void **) &working_dir)) {
3224
snprintf(tmp, MAX_TMP_BUF_LEN, "/bin/rm -rf %s", working_dir);
3225
NOWARN_UNUSED_RETURN(system(tmp));
3227
if (submit_from_page)
3228
xfree(submit_from_page);
3229
submit_from_page = xstrdup(HTML_OTW_UPGRADE_FILE);
3230
if (whc->top_level_render_file)
3231
xfree(whc->top_level_render_file);
3232
whc->top_level_render_file = xstrdup(submit_from_page);
3235
// start upgrade = render upgrade page + spawn traffic_shell.cgi script
3237
link = WebHttpGetLink_Xmalloc(HTML_DEFAULT_MONITOR_FILE);
3240
cgi_path = WebHttpAddDocRoot_Xmalloc(whc, HTML_OTW_UPGRADE_CGI_FILE);
3241
int old_euid, old_egid;
3242
Config_User_Root(&old_euid);
3243
Config_Grp_Root(&old_egid);
3244
spawn_cgi(whc, cgi_path, NULL, true, true);
3245
Config_User_Inktomi(old_euid);
3246
Config_Grp_Inktomi(old_egid);
3247
if (submit_from_page)
3248
xfree(submit_from_page);
3249
submit_from_page = xstrdup("/upgrade.ink");
3250
xfree((char *) cgi_path);
3254
if (submit_from_page) {
3255
err = WebHttpRender(whc, submit_from_page);
3256
xfree(submit_from_page);
3258
err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
3263
//-------------------------------------------------------------------------
3265
//-------------------------------------------------------------------------
3268
handle_default(WebHttpContext * whc, const char *file)
3271
char *doc_root_file;
3273
time_t file_date_gmt;
3276
httpMessage *request = whc->request;
3277
httpResponse *response_hdr = whc->response_hdr;
3278
textBuffer *response_bdy = whc->response_bdy;
3280
const char *request_file = file;
3281
time_t request_file_ims;
3282
int request_file_len;
3284
// requests are supposed to begin with a "/"
3285
if (*request_file != '/') {
3286
response_hdr->setStatus(STATUS_NOT_FOUND);
3287
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
3288
return WEB_HTTP_ERR_REQUEST_ERROR;
3290
// first, make sure there are no ..'s in path or root directory
3291
// access in name for security reasons
3292
if (strstr(request_file, "..") != NULL || strncmp(request_file, "//", 2) == 0) {
3293
response_hdr->setStatus(STATUS_FORBIDDEN);
3294
WebHttpSetErrorResponse(whc, STATUS_FORBIDDEN);
3295
return WEB_HTTP_ERR_REQUEST_ERROR;
3298
if (strcmp("/", request_file) == 0) {
3299
request_file = whc->default_file;
3301
// check file type and set document type if appropiate
3302
request_file_len = strlen(request_file);
3303
if (strcmp(request_file + (request_file_len - 4), ".htm") == 0) {
3304
response_hdr->setContentType(TEXT_HTML);
3305
} else if (strcmp(request_file + (request_file_len - 5), ".html") == 0) {
3306
response_hdr->setContentType(TEXT_HTML);
3307
} else if (strcmp(request_file + (request_file_len - 4), ".css") == 0) {
3308
response_hdr->setContentType(TEXT_CSS);
3309
} else if (strcmp(request_file + (request_file_len - 4), ".gif") == 0) {
3310
response_hdr->setContentType(IMAGE_GIF);
3311
} else if (strcmp(request_file + (request_file_len - 4), ".jpg") == 0) {
3312
response_hdr->setContentType(IMAGE_JPEG);
3313
} else if (strcmp(request_file + (request_file_len - 5), ".jpeg") == 0) {
3314
response_hdr->setContentType(IMAGE_JPEG);
3315
} else if (strcmp(request_file + (request_file_len - 4), ".png") == 0) {
3316
response_hdr->setContentType(IMAGE_PNG);
3317
} else if (strcmp(request_file + (request_file_len - 4), ".jar") == 0) {
3318
response_hdr->setContentType(APP_JAVA);
3319
} else if (strcmp(request_file + (request_file_len - 3), ".js") == 0) {
3320
response_hdr->setContentType(APP_JAVASCRIPT);
3321
} else if (strcmp(request_file + (request_file_len - 4), ".der") == 0) {
3322
response_hdr->setContentType(APP_X509);
3323
} else if (strcmp(request_file + (request_file_len - 4), ".dat") == 0) {
3324
response_hdr->setContentType(APP_AUTOCONFIG);
3325
response_hdr->setCachable(0);
3326
} else if (strcmp(request_file + (request_file_len - 4), ".pac") == 0) {
3327
response_hdr->setContentType(APP_AUTOCONFIG);
3328
// Fixed INKqa04312 - 02/21/1999 elam
3329
// We don't want anyone to cache .pac files.
3330
response_hdr->setCachable(0);
3331
} else if (strcmp(request_file + (request_file_len - 4), ".zip") == 0) {
3332
response_hdr->setContentType(APP_ZIP);
3334
// don't serve file types that we don't know about; helps to lock
3335
// down the webserver. for example, when serving files out the
3336
// etc/trafficserver/plugins directory, we don't want to allow the users to
3337
// access the .so/.dll plugin files.
3338
response_hdr->setStatus(STATUS_NOT_FOUND);
3339
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
3340
return WEB_HTTP_ERR_REQUEST_ERROR;
3343
// append the appropriate doc_root on to the file
3344
doc_root_file = WebHttpAddDocRoot_Xmalloc(whc, request_file);
3346
// open the requested file
3347
if ((h_file = WebFileOpenR(doc_root_file)) == WEB_HANDLE_INVALID) {
3348
//could not find file
3349
xfree(doc_root_file);
3350
response_hdr->setStatus(STATUS_NOT_FOUND);
3351
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
3352
return WEB_HTTP_ERR_REQUEST_ERROR;
3355
file_size = WebFileGetSize(h_file);
3356
file_date_gmt = WebFileGetDateGmt(h_file);
3357
request_file_ims = request->getModTime();
3359
// special logic for the autoconf port
3360
if ((whc->server_state & WEB_HTTP_SERVER_STATE_AUTOCONF) && (file_size == 0)) {
3361
response_hdr->setStatus(STATUS_NOT_FOUND);
3362
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
3363
WebFileClose(h_file);
3364
xfree(doc_root_file);
3365
return WEB_HTTP_ERR_REQUEST_ERROR;
3367
// Check to see if the clients copy is up to date. Ignore the
3368
// stupid content length that Netscape Navigator sends on the
3369
// If-Modified-Since line since it not in the HTTP 1.0 standard
3371
// Since the client sends If-Modified-Since in GMT, make sure that
3372
// we transform mtime to GMT
3373
if (request_file_ims != -1 && request_file_ims >= file_date_gmt) {
3374
response_hdr->setStatus(STATUS_NOT_MODIFIED);
3376
// fetch the file from disk to memory
3377
response_hdr->setStatus(STATUS_OK);
3378
response_hdr->setLength(file_size);
3379
while (response_bdy->rawReadFromFile(h_file) > 0);
3381
// set the document last-modified header
3382
response_hdr->setLastMod(file_date_gmt);
3384
WebFileClose(h_file);
3385
xfree(doc_root_file);
3387
return WEB_HTTP_ERR_OKAY;
3393
//-------------------------------------------------------------------------
3395
//-------------------------------------------------------------------------
3398
read_request(WebHttpContext * whc)
3401
const int buffer_size = 2048;
3402
char *buffer = (char *) alloca(buffer_size);
3404
httpMessage *request = whc->request;
3405
httpResponse *response_hdr = whc->response_hdr;
3407
// first get the request line
3408
if (sigfdrdln(whc->si, buffer, buffer_size) < 0) {
3409
// if we can not get the request line, update the status code so
3410
// it can get logged correctly but do not bother trying to send a
3412
response_hdr->setStatus(STATUS_BAD_REQUEST);
3413
return WEB_HTTP_ERR_REQUEST_FATAL;
3417
if (request->addRequestLine(buffer) != 0) {
3418
response_hdr->setStatus(STATUS_BAD_REQUEST);
3419
WebHttpSetErrorResponse(whc, STATUS_BAD_REQUEST);
3420
return WEB_HTTP_ERR_REQUEST_ERROR;
3422
// Check for a scheme we do not understand
3424
// If we undertand the scheme, it has
3426
if (request->getScheme() == SCHEME_UNKNOWN) {
3427
response_hdr->setStatus(STATUS_NOT_IMPLEMENTED);
3428
WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
3429
return WEB_HTTP_ERR_REQUEST_ERROR;
3432
if (request->getMethod() != METHOD_GET && request->getMethod() != METHOD_POST && request->getMethod() != METHOD_HEAD) {
3433
response_hdr->setStatus(STATUS_NOT_IMPLEMENTED);
3434
WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
3435
return WEB_HTTP_ERR_REQUEST_ERROR;
3437
// Read the headers of http request line by line until
3438
// we get a line that is solely composed of "\r" (or
3439
// just "" since not everyone follows the HTTP standard
3442
if (sigfdrdln(whc->si, buffer, buffer_size) < 0) {
3443
response_hdr->setStatus(STATUS_BAD_REQUEST);
3444
return WEB_HTTP_ERR_REQUEST_FATAL;
3446
request->addHeader(buffer);
3447
} while (strcmp(buffer, "\r") != 0 && *buffer != '\0');
3449
// If there is a content body, read it in
3450
if (request->addRequestBody(whc->si) < 0) {
3451
// There was error on reading the response body
3452
response_hdr->setStatus(STATUS_BAD_REQUEST);
3453
WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
3454
return WEB_HTTP_ERR_REQUEST_ERROR;
3457
// Drain read channel: In the case of Linux, OS sends reset to the
3458
// socket if we close it when there is data left on it ot be read
3459
// (in compliance with TCP). This causes problems with the "POST"
3460
// method. (for example with update.html). With IE, we found ending
3461
// "\r\n" were not read. The following work around is to read all
3462
// that is left in the socket before closing it. The same problem
3463
// applies for Windows 2000 as well.
3464
#if !defined(_WIN32)
3465
#define MAX_DRAIN_BYTES 32
3466
// INKqa11524: If the user is malicious and keeps sending us data,
3467
// we'll go into an infinite spin here. Fix is to only drain up
3468
// to 32 bytes to allow for funny browser behavior but to also
3469
// prevent reading forever.
3470
int drain_bytes = 0;
3471
if (fcntl(whc->si.fd, F_SETFL, O_NONBLOCK) >= 0) {
3473
while ((read(whc->si.fd, &ch, 1) > 0) && (drain_bytes < MAX_DRAIN_BYTES)) {
3480
if (ioctlsocket(whc->si.fd, FIONREAD, &i) != SOCKET_ERROR) {
3482
char *buf = (char *) alloca(i * sizeof(char));
3483
read_socket(whc->si.fd, buf, i);
3489
return WEB_HTTP_ERR_OKAY;
3493
//-------------------------------------------------------------------------
3495
//-------------------------------------------------------------------------
3498
write_response(WebHttpContext * whc)
3503
// Make sure that we have a content length
3504
if (whc->response_hdr->getLength() < 0) {
3505
whc->response_hdr->setLength(whc->response_bdy->spaceUsed());
3507
whc->response_hdr->writeHdr(whc->si);
3508
if (whc->request->getMethod() != METHOD_HEAD) {
3509
buf_p = whc->response_bdy->bufPtr();
3510
bytes_to_write = whc->response_bdy->spaceUsed();
3512
while (bytes_to_write) {
3513
bytes_written = socket_write(whc->si, buf_p, bytes_to_write);
3514
if (bytes_written < 0) {
3515
if (errno == EINTR || errno == EAGAIN)
3518
return WEB_HTTP_ERR_FAIL;
3520
bytes_to_write -= bytes_written;
3521
buf_p += bytes_written;
3525
return WEB_HTTP_ERR_OKAY;
3528
//-------------------------------------------------------------------------
3530
//-------------------------------------------------------------------------
3533
process_query(WebHttpContext * whc)
3538
// processFormSubmission will substituteUnsafeChars()
3539
if ((ht = processFormSubmission((char *) (whc->request->getQuery()))) != NULL) {
3540
whc->query_data_ht = ht;
3541
// extract some basic info for easier access later
3542
if (ink_hash_table_lookup(ht, "mode", (void **) &value)) {
3543
if (strcmp(value, "1") == 0)
3544
whc->request_state |= WEB_HTTP_STATE_CONFIGURE;
3546
if (ink_hash_table_lookup(ht, "detail", (void **) &value)) {
3547
if (strcmp(value, "more") == 0)
3548
whc->request_state |= WEB_HTTP_STATE_MORE_DETAIL;
3550
err = WEB_HTTP_ERR_OKAY;
3552
err = WEB_HTTP_ERR_FAIL;
3557
//-------------------------------------------------------------------------
3559
//-------------------------------------------------------------------------
3562
process_post(WebHttpContext * whc)
3566
// processFormSubmission will substituteUnsafeChars()
3567
if ((ht = processFormSubmission(whc->request->getBody())) != NULL) {
3568
whc->post_data_ht = ht;
3569
err = WEB_HTTP_ERR_OKAY;
3571
err = WEB_HTTP_ERR_FAIL;
3576
//-------------------------------------------------------------------------
3577
// signal_handler_init
3578
//-------------------------------------------------------------------------
3581
signal_handler_do_nothing(int x)
3583
// A small function thats whole purpose is to give the signal
3584
// handler for breaking out of a network read, somethng to call
3589
signal_handler_init()
3591
// Setup signal handling. We want to able to unstick stuck socket
3592
// connections. This is accomplished by a watcher thread doing a
3593
// half close on the incoming socket after a timeout. To break, out
3594
// the current read which is likely stuck we have a signal handler
3595
// on SIGUSR1 which does nothing except by side effect of break the
3596
// read. All future reads from the socket should fail since
3597
// incoming traffic is shutdown on the connection and thread should
3599
#if !defined(_WIN32)
3600
sigset_t sigsToBlock;
3601
// FreeBSD and Linux use SIGUSR1 internally in the threads library
3602
#if !defined(linux) && !defined(freebsd) && !defined(darwin)
3603
// Set up the handler for SIGUSR1
3604
struct sigaction sigHandler;
3605
sigHandler.sa_handler = signal_handler_do_nothing;
3606
sigemptyset(&sigHandler.sa_mask);
3607
sigHandler.sa_flags = 0;
3608
sigaction(SIGUSR1, &sigHandler, NULL);
3610
// Block all other signals
3611
sigfillset(&sigsToBlock);
3612
sigdelset(&sigsToBlock, SIGUSR1);
3613
ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
3615
return WEB_HTTP_ERR_OKAY;
3618
//-------------------------------------------------------------------------
3620
//-------------------------------------------------------------------------
3623
ssl_init(WebHttpContext * whc)
3625
SSL *SSL_con = NULL;
3626
unsigned int sslErrno;
3627
char ssl_Error[256];
3628
SSL_con = SSL_new(whc->ssl_ctx);
3629
SSL_set_fd(SSL_con, whc->si.fd);
3630
if (SSL_accept(SSL_con) < 0) {
3631
sslErrno = ERR_get_error();
3632
ERR_error_string(sslErrno, ssl_Error);
3633
mgmt_log(stderr, "[ssl_init] SSL_accept failed: %s", ssl_Error);
3634
return WEB_HTTP_ERR_FAIL;
3636
whc->si.SSLcon = SSL_con;
3638
return WEB_HTTP_ERR_OKAY;
3641
//-------------------------------------------------------------------------
3643
//-------------------------------------------------------------------------
3646
ssl_free(WebHttpContext * whc)
3648
if (whc->si.SSLcon != NULL) {
3649
SSL_free((SSL *) whc->si.SSLcon);
3652
return WEB_HTTP_ERR_OKAY;
3655
//-------------------------------------------------------------------------
3657
//-------------------------------------------------------------------------
3663
static int initialized = 0;
3665
if (initialized != 0) {
3666
mgmt_log(stderr, "[WebHttpInit] error, initialized twice (%d)", initialized);
3670
// initialize autoconf allow files
3671
g_autoconf_allow_ht = ink_hash_table_create(InkHashTableKeyType_String);
3672
ink_hash_table_insert(g_autoconf_allow_ht, "/proxy.pac", NULL);
3673
ink_hash_table_insert(g_autoconf_allow_ht, "/wpad.dat", NULL);
3674
ink_hash_table_insert(g_autoconf_allow_ht, "/public_key.der", NULL);
3675
ink_hash_table_insert(g_autoconf_allow_ht, "/synthetic.txt", NULL);
3677
// initialize submit bindings
3678
g_submit_bindings_ht = ink_hash_table_create(InkHashTableKeyType_String);
3679
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_ALARM_FILE, (void *) handle_submit_alarm);
3680
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_MGMT_AUTH_FILE, (void *) handle_submit_mgmt_auth);
3681
//ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FILE, handle_submit_snapshot);
3682
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FILESYSTEM,
3683
(void *) handle_submit_snapshot_to_filesystem);
3684
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FTPSERVER,
3685
(void *) handle_submit_snapshot_to_ftpserver);
3686
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FLOPPY, (void *) handle_submit_snapshot_to_floppy);
3687
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_INSPECTOR_FILE, (void *) handle_submit_inspector);
3688
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_INSPECTOR_DPY_FILE, (void *) handle_submit_inspector_display);
3689
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_VIEW_LOGS_FILE, (void *) handle_submit_view_logs);
3690
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_UPDATE_FILE, (void *) handle_submit_update);
3691
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_UPDATE_CONFIG, (void *) handle_submit_update_config);
3692
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_CONFIG_DISPLAY, (void *) handle_submit_config_display);
3693
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_NET_CONFIG, (void *) handle_submit_net_config);
3694
ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_OTW_UPGRADE_FILE, (void *) handle_submit_otw_upgrade);
3695
// initialize file bindings
3696
g_file_bindings_ht = ink_hash_table_create(InkHashTableKeyType_String);
3697
ink_hash_table_insert(g_file_bindings_ht, HTML_CHART_FILE, (void *) handle_chart);
3698
ink_hash_table_insert(g_file_bindings_ht, HTML_BACKDOOR_CONFIG_FILES, (void *) handle_config_files);
3699
ink_hash_table_insert(g_file_bindings_ht, HTML_BACKDOOR_DEBUG_LOGS, (void *) handle_debug_logs);
3700
ink_hash_table_insert(g_file_bindings_ht, HTML_SYNTHETIC_FILE, (void *) handle_synthetic);
3702
// initialize extension bindings
3703
g_extn_bindings_ht = ink_hash_table_create(InkHashTableKeyType_String);
3704
ink_hash_table_insert(g_extn_bindings_ht, ".cgi", (void *) handle_cgi_extn);
3705
ink_hash_table_insert(g_extn_bindings_ht, ".ink", (void *) handle_ink_extn);
3707
// initialize the configurator editing bindings which binds
3708
// configurator display filename (eg. f_cache_config.ink) to
3709
// its mgmt API config file type (INKFileNameT)
3710
g_display_config_ht = ink_hash_table_create(InkHashTableKeyType_String);
3711
ink_hash_table_insert(g_display_config_ht, HTML_FILE_CACHE_CONFIG, (void *) INK_FNAME_CACHE_OBJ);
3712
ink_hash_table_insert(g_display_config_ht, HTML_FILE_HOSTING_CONFIG, (void *) INK_FNAME_HOSTING);
3713
ink_hash_table_insert(g_display_config_ht, HTML_FILE_ICP_CONFIG, (void *) INK_FNAME_ICP_PEER);
3714
ink_hash_table_insert(g_display_config_ht, HTML_FILE_IP_ALLOW_CONFIG, (void *) INK_FNAME_IP_ALLOW);
3715
ink_hash_table_insert(g_display_config_ht, HTML_FILE_MGMT_ALLOW_CONFIG, (void *) INK_FNAME_MGMT_ALLOW);
3716
ink_hash_table_insert(g_display_config_ht, HTML_FILE_PARENT_CONFIG, (void *) INK_FNAME_PARENT_PROXY);
3717
ink_hash_table_insert(g_display_config_ht, HTML_FILE_PARTITION_CONFIG, (void *) INK_FNAME_PARTITION);
3718
ink_hash_table_insert(g_display_config_ht, HTML_FILE_REMAP_CONFIG, (void *) INK_FNAME_REMAP);
3719
ink_hash_table_insert(g_display_config_ht, HTML_FILE_SOCKS_CONFIG, (void *) INK_FNAME_SOCKS);
3720
ink_hash_table_insert(g_display_config_ht, HTML_FILE_SPLIT_DNS_CONFIG, (void *) INK_FNAME_SPLIT_DNS);
3721
ink_hash_table_insert(g_display_config_ht, HTML_FILE_UPDATE_CONFIG, (void *) INK_FNAME_UPDATE_URL);
3722
ink_hash_table_insert(g_display_config_ht, HTML_FILE_VADDRS_CONFIG, (void *) INK_FNAME_VADDRS);
3724
// initialize other modules
3727
WebHttpSessionInit();
3729
WebHttpRenderInit();
3736
//-------------------------------------------------------------------------
3737
// WebHttpHandleConnection
3739
// Handles http requests across the web management port
3740
//-------------------------------------------------------------------------
3743
WebHttpHandleConnection(WebHttpConInfo * whci)
3746
int err = WEB_HTTP_ERR_OKAY;
3748
WebHttpContext *whc;
3749
WebHttpHandler handler;
3756
if ((whc = WebHttpContextCreate(whci)) == NULL)
3757
goto Ltransaction_close;
3758
if (signal_handler_init() != WEB_HTTP_ERR_OKAY)
3759
goto Ltransaction_close;
3760
if (whc->server_state & WEB_HTTP_SERVER_STATE_SSL_ENABLED)
3761
if (ssl_init(whc) != WEB_HTTP_ERR_OKAY)
3762
goto Ltransaction_close;
3765
if ((err = read_request(whc)) != WEB_HTTP_ERR_OKAY)
3769
if (whc->server_state & WEB_HTTP_SERVER_STATE_AUTH_ENABLED)
3770
if (WebHttpAuthenticate(whc) != WEB_HTTP_ERR_OKAY)
3771
goto Ltransaction_send;
3773
// get our file information
3774
file = (char *) (whc->request->getFile());
3775
if (strcmp("/", file) == 0) {
3776
file = (char *) (whc->default_file);
3779
Debug("web2", "[WebHttpHandleConnection] request file: %s", file);
3782
if (whc->server_state & WEB_HTTP_SERVER_STATE_AUTOCONF) {
3784
// security concern: special treatment if we're handling a request
3785
// on the autoconf port. can't have users downloading arbitrary
3786
// files under the config directory!
3787
if (!ink_hash_table_isbound(g_autoconf_allow_ht, file)) {
3788
mgmt_elog(stderr,"[WebHttpHandleConnection] %s not valid autoconf file",file);
3789
whc->response_hdr->setStatus(STATUS_NOT_FOUND);
3790
WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
3791
goto Ltransaction_send;
3795
if (WebHttpTreeReturnRefresh(file)) {
3796
// if we are handling a monitor/mrtg page, configure it to refresh
3797
if (strncmp(file, "/monitor/", 9) == 0) {
3798
whc->response_hdr->setRefresh(wGlobals.refreshRate);
3799
} else if (strncmp(file, "/mrtg/", 6) == 0) {
3800
whc->response_hdr->setRefresh(REFRESH_RATE_MRTG);
3802
whc->response_hdr->setRefresh(wGlobals.refreshRate);
3806
// Make a note if we are a plugin. Being a plugin will affect our
3807
// doc_root and how request files and doc_roots are joined to
3808
// generate an absolute path. See WebHttpAddDocRoot_Xmalloc()
3809
if (strncmp(file, "/plugins/", 9) == 0) {
3810
whc->request_state |= WEB_HTTP_STATE_PLUGIN;
3818
// check submit_binding;
3819
// if nothing, check file_binding;
3820
// if nothing, check extn_binding;
3821
// if still nothing, use the default handler;
3822
if (ink_hash_table_lookup(g_submit_bindings_ht, file, (void **) &handler)) {
3823
// workaround: sometimes we receive a GET for our submit cgi's
3824
// (rather than a resubmitted POST). In this case, just render
3825
// the default page since we can't do much else
3826
if (whc->request->getMethod() != METHOD_POST) {
3827
if ((strcmp(file, HTML_SUBMIT_INSPECTOR_DPY_FILE) != 0) && (strcmp(file, HTML_SUBMIT_CONFIG_DISPLAY) != 0)) {
3828
err = WebHttpRender(whc, HTML_DEFAULT_MONITOR_FILE);
3834
// only allow one submission at a time
3835
ink_mutex_acquire(&wGlobals.submitLock);
3836
err = handler(whc, file);
3837
ink_mutex_release(&wGlobals.submitLock);
3839
if (!ink_hash_table_lookup(g_file_bindings_ht, file, (void **) &handler)) {
3841
while (*extn != '\0')
3843
while ((extn > file) && (*extn != '.'))
3845
if (!ink_hash_table_lookup(g_extn_bindings_ht, extn, (void **) &handler)) {
3846
handler = handle_default;
3849
err = handler(whc, file);
3855
case WEB_HTTP_ERR_OKAY:
3856
case WEB_HTTP_ERR_REQUEST_ERROR:
3857
goto Ltransaction_send;
3858
case WEB_HTTP_ERR_FAIL:
3859
case WEB_HTTP_ERR_REQUEST_FATAL:
3861
goto Ltransaction_close;
3867
if ((err = write_response(whc)) != WEB_HTTP_ERR_OKAY)
3868
goto Ltransaction_close;
3870
// close the connection before logging it to reduce latency
3872
shutdown(whc->si.fd, 1);
3874
if (fcntl(whc->si.fd, F_SETFL, O_NONBLOCK) >= 0) {
3875
while ((read(whc->si.fd, &ch, 1) > 0) && (drain_bytes < MAX_DRAIN_BYTES)) {
3880
close_socket(whc->si.fd);
3884
if (wGlobals.logFD >= 0)
3885
WebHttpLogTransaction(whc);
3889
// if we didn't close already, close connection
3890
if (whc->si.fd != -1) {
3892
shutdown(whc->si.fd, 1);
3894
if (fcntl(whc->si.fd, F_SETFL, O_NONBLOCK) >= 0) {
3895
while ((read(whc->si.fd, &ch, 1) > 0) && (drain_bytes < MAX_DRAIN_BYTES)) {
3900
close_socket(whc->si.fd);
3903
if (whc->server_state & WEB_HTTP_SERVER_STATE_SSL_ENABLED)
3907
WebHttpContextDestroy(whc);
3913
//-------------------------------------------------------------------------
3914
// WebHttpSetErrorResponse
3916
// Formulates a page to return on an HttpStatus condition
3917
//-------------------------------------------------------------------------
3920
WebHttpSetErrorResponse(WebHttpContext * whc, HttpStatus_t error)
3923
//-----------------------------------------------------------------------
3924
// FIXME: HARD-CODED HTML HELL!!!
3925
//-----------------------------------------------------------------------
3927
static const char a[] = "<HTML>\n<Head>\n<TITLE>";
3928
static const char b[] = "</TITLE>\n</HEAD>\n<BODY bgcolor=\"#FFFFFF\"><h1>\n";
3929
static const char c[] = "</h1>\n</BODY>\n</HTML>\n";
3930
int errorMsgLen = strlen(httpStatStr[error]);
3933
whc->response_bdy->reUse();
3935
// fill in the buffer
3936
whc->response_bdy->copyFrom(a, strlen(a));
3937
whc->response_bdy->copyFrom(httpStatStr[error], errorMsgLen);
3938
whc->response_bdy->copyFrom(b, strlen(b));
3939
whc->response_bdy->copyFrom(httpStatStr[error], errorMsgLen);
3940
whc->response_bdy->copyFrom(c, strlen(c));
3944
//-------------------------------------------------------------------------
3945
// WebHttpAddDocRoot_Xmalloc
3946
//-------------------------------------------------------------------------
3949
WebHttpAddDocRoot_Xmalloc(WebHttpContext * whc, const char *file)
3953
char *doc_root_file;
3956
is_plugin = whc->request_state & WEB_HTTP_STATE_PLUGIN;
3958
file_len = strlen(file);
3959
file_len += is_plugin ? strlen(whc->plugin_doc_root) : strlen(whc->doc_root);
3960
doc_root_file = (char *) xmalloc(file_len + 1);
3963
ink_strncpy(doc_root_file, whc->plugin_doc_root, file_len);
3964
strncat(doc_root_file, file + strlen("/plugins"), file_len - strlen(doc_root_file));
3966
ink_strncpy(doc_root_file, whc->doc_root, file_len);
3967
strncat(doc_root_file, file, file_len - strlen(doc_root_file));
3970
return doc_root_file;