antoniop
committed
on 16 Mar 22
Enforce only valid mime types
openacs-4/.../www/delivery/servlet.tcl (+41 -43)
1 1 ad_page_contract {
2 2
3 3     Main tcl procedures to handle colloquia with java rte applet
4 4
5 5     @author Michele Slocovich (michele@sii.it)
6 6     @creation-date 2004-09-27
7 7     @cvs-id $Id$
8 8 } {
9 9     functionCalled:notnull
10 10     data:optional
11 11 } -properties {
12 12 } -validate {
13 13 } -errors {
14 14 }
15   ns_log Notice "Huh? servlet function called $functionCalled"
  15 ns_log Notice " servlet function called $functionCalled"
16 16 if { [info exists data] } {
17       ns_log Notice "Huh? data: $data"
  17     ns_log Notice " data: $data"
18 18 }
19 19
20 20 #set the following accordingly to debug or Notice
21   set basiclevel "Notice"
22   set tracelevel "Notice"
  21 set basiclevel "Debug"
  22 set tracelevel "Debug"
23 23 #tracelevel debug will show messages only at debug level
24 24 #tracelevel Notice will show all messages. same goes for basiclevel
25 25 #see index.tcl for setting java/javascript debugging by setting debuglevel
26 26
27 27 #try to circumvent browsers caching strategies
28 28 set s [ns_set new]
29 29 ns_set put $s "Pragma" "No-Cache"
30 30 ns_set put $s "Expires" "0"
31 31 ns_set move $s [ns_conn outputheaders]
32 32 ns_set move [ns_conn outputheaders] $s
33 33
34 34 #fetching information
35 35 set user_id [ad_conn user_id]
36 36 acs_user::get -user_id $user_id -array user
37 37 set username $user(username)
38   ns_log $tracelevel "Huh?---------------------------------------"
39   ns_log $basiclevel "Huh?        LMS Rte server START"
40   ns_log $tracelevel "Huh?---------------------------------------"
41   ns_log $tracelevel "Huh?username: $username"
  38 ns_log $tracelevel "---------------------------------------"
  39 ns_log $basiclevel "        LMS Rte server START"
  40 ns_log $tracelevel "---------------------------------------"
  41 ns_log $tracelevel "username: $username"
42 42 set currentcourse [ad_get_client_property lorsm currentcourse]
43   ns_log $tracelevel "Huh?man_id: $currentcourse"
  43 ns_log $tracelevel "man_id: $currentcourse"
44 44 #this is not used in this proc, so far
45 45
46 46 set currentpage [ad_get_client_property lorsm ims_id]
47 47 set initedonpage [ad_get_client_property lorsm initedonpage]
48 48
49   ns_log $basiclevel "Huh?lorsm ims_item_id $currentpage"
50   ns_log $basiclevel "Huh?lorsm initedonpage $initedonpage"
  49 ns_log $basiclevel "lorsm ims_item_id $currentpage"
  50 ns_log $basiclevel "lorsm initedonpage $initedonpage"
51 51
52 52 if { ! ($currentpage>0) } {
53       ns_log $basiclevel "Huh?SCORM missing ims_item_id : $currentpage"
  53     ns_log $basiclevel "SCORM missing ims_item_id : $currentpage"
54 54 }
55 55
56 56 set community_id [lors::get_community_id]
57 57
58   ns_log $basiclevel "Huh?SCORM user: $user_id course: $currentcourse ims_item_id: $currentpage community_id: $community_id"
59  
60 58 if { $user_id == 0 } {
61 59     #http 401 is unauthorized
62 60     ns_return 401 text/plain "Error=101,ErrorDescription=\"Not logged in\""
63 61 }
64 62
65 63 if { $currentcourse == "" } {
66 64     #http 303 is error: but the answer should be found elsewhere
67 65     ns_return 303 text/plain "Error=102,ErrorDescription=\"No current course (how did you get here?)\""
68 66 }
69 67
70 68 if { ! [info exists functionCalled] } {
71 69     #http 400 BAD request: returned as well as when functionCalled is nonsense (see end of switch)
72 70     ns_return 400 text/plain "Error=104,ErrorDescription=\"No function specified\""
73 71 }
74 72
75 73 set currenttrackid [ad_get_client_property lorsm currenttrackid]
76 74 set lorsmstudenttrack [ad_get_client_property lorsm studenttrack]
77 75
78 76 set package_id [ad_conn package_id]
79 77
80   ns_log $basiclevel "Huh?SCORM $functionCalled "
81   ns_log $basiclevel "Huh?SCORM tracking (client properties): currenttrackid: $currenttrackid lorsmtrack: $lorsmstudenttrack "
  78 ns_log $basiclevel "SCORM $functionCalled "
  79 ns_log $basiclevel "SCORM tracking (client properties): currenttrackid: $currenttrackid lorsmtrack: $lorsmstudenttrack "
82 80
83 81 ad_get_user_info
84 82 set name $last_name
85 83 #seems ADL wants a comma between lastname and christian
86 84 append name ", "
87 85 append name $first_names
88 86
89 87 if { $initedonpage != $currentpage } {
90 88     if { $functionCalled != "cmigetcat" } {
91 89         if { $functionCalled != "keepalive" } {
92 90             ns_log warning "SCORM jumping to different courses WITHOUT init!!!"
93 91         } else {
94 92             ns_log warning "SCORM keepalive still alive after LMSFinish"
95 93         }
96 94
97 95         #c'e' stato un cambiamento di item
98 96         set lorsmstudenttrack ""
99 97         ad_set_client_property lorsm initedonpage $currentpage
100 98     }
101 99 }
102 100
103 101 switch -regexp $functionCalled {
104 102     null -
105 103     keepalive {
106 104         ns_return 200 text/plain "OK"
107 105         ns_log warning "SCORM Keepalive"
108 106
109 107     } cmigetcat {
110           ns_log $tracelevel "Huh?---------------------------------------"
111           ns_log $basiclevel "Huh?        LMSInitialise "
112           ns_log $tracelevel "Huh?---------------------------------------"
  108         ns_log $tracelevel "---------------------------------------"
  109         ns_log $basiclevel "        LMSInitialise "
  110         ns_log $tracelevel "---------------------------------------"
113 111
114 112         if { $initedonpage != $currentpage } {
115 113             #c'e' stato un cambiamento di item
116 114             set lorsmstudenttrack ""
117 115             ad_set_client_property lorsm initedonpage $currentpage
118 116         }
119 117
120 118         if { $lorsmstudenttrack == 0 || $lorsmstudenttrack == ""  } {
121                   ns_log $basiclevel "Huh?SCORM : lorsm student new track "
  119                 ns_log $basiclevel "SCORM : lorsm student new track "
122 120             #here track id was not set (course is not lors-trackable)
123 121             #we should first try to see if we find an already open track in lorsm.track
124 122             set lorsmstudenttrack [lorsm::track::new \
125 123                                     -user_id $user_id \
126 124                                     -community_id $community_id \
127 125                                     -course_id $currentcourse]
128 126
129 127             ad_set_client_property lorsm studenttrack $lorsmstudenttrack
130               ns_log $basiclevel "Huh?SCORM tracking has in any case created a lorsm_student_tracking track_id: $lorsmstudenttrack"
  128             ns_log $basiclevel "SCORM tracking has in any case created a lorsm_student_tracking track_id: $lorsmstudenttrack"
131 129             if { ! [ db_0or1row isanysuspendedsession {} ] } {
132 130                                         #faccio un nuovo trackid
133 131                                         #and
134 132                                         #   not (
135 133                                         #       cmi.lesson_status = 'completed'
136 134                                         #   or
137 135                                         #       cmi.lesson_status = 'passed'
138 136                                         #   )
139 137                                         #we create a new track which is going to be the new 'master track' for this cmi data set
140 138                 set currenttrackid $lorsmstudenttrack
141                   ns_log $basiclevel "Huh?SCORM new track id: $currenttrackid"
  139                 ns_log $basiclevel "SCORM new track id: $currenttrackid"
142 140             } else {
143 141                 set currenttrackid $track_id
144                   ns_log $basiclevel "Huh?SCORM found a lorsm_cmi_core track with a non completed nor passed session."
  142                 ns_log $basiclevel "SCORM found a lorsm_cmi_core track with a non completed nor passed session."
145 143             }
146 144
147 145         } else {
148               ns_log $basiclevel "Huh?SCORM already has current session (=$lorsmstudenttrack) (istrackable is on): going to check if the session is ok for current item"
  146             ns_log $basiclevel "SCORM already has current session (=$lorsmstudenttrack) (istrackable is on): going to check if the session is ok for current item"
149 147             #now we look for the existance of a lorsm.cmi.core track id for this user / course / class which is still not completed
150 148             if { ! [ db_0or1row isanysuspendedsession {} ] } {
151 149                                                     #and
152 150                                                     #        not (
153 151                                                     #                cmi.lesson_status = 'completed'
154 152                                                     #        or
155 153                                                     #                cmi.lesson_status = 'passed'
156 154                                                     #        )
157 155                 #the reasoning here is as follows: i had a $lorsmstudenttrack
158 156                 #but not track for the course in lorsm_cmi_core. therefore i need to change the
159 157                 #"student" track
160 158                 set lorsmstudenttrack [lorsm::track::new \
161 159                                         -user_id $user_id \
162 160                                         -community_id $community_id \
163 161                                         -course_id $currentcourse]
164 162                 ad_set_client_property lorsm studenttrack $lorsmstudenttrack
165 163                 set currenttrackid $lorsmstudenttrack
166 164             } else {
167 165                 set currenttrackid $track_id
168 166             }
169 167         }
170 168         #at this stage currenttrackid is the value it should have in lorsm_cmi_core
171 169
172 170         if { ![ db_0or1row istherealready {} ] } {
173               ns_log $basiclevel "Huh?SCORM new RTE lorsm_cmi_core: id $currenttrackid"
  171             ns_log $basiclevel "SCORM new RTE lorsm_cmi_core: id $currenttrackid"
174 172             #get initialization data from manifest data already imported
175 173             db_0or1row get_adlcp_student_data {}
176 174
177               ns_log $basiclevel "Huh?SCORM data for lorsm_cmi_student_data is $datafromlms, $maxtimeallowed, $timelimitaction, $masteryscore"
  175             ns_log $basiclevel "SCORM data for lorsm_cmi_student_data is $datafromlms, $maxtimeallowed, $timelimitaction, $masteryscore"
178 176             #
179 177             # lesson_location is the bookmark.
180 178             # lesson_status is initialized to 'not attempted'
181 179             #
182 180             db_dml lmsinitialize {}
183 181
184               ns_log $basiclevel "Huh?SCORM Data inserting into lorsm_student_data $currenttrackid $username $maxtimeallowed"
  182             ns_log $basiclevel "SCORM Data inserting into lorsm_student_data $currenttrackid $username $maxtimeallowed"
185 183             db_dml lmsinitialize2 {}
186 184
187 185             ad_set_client_property lorsm currenttrackid $currenttrackid
188 186             db_0or1row istherealready {}
189 187
190 188             #AURALOG HACK
191 189             #adjust on a per-server basis
192 190             #if { $currentcourse == 6280 } {
193 191             #set student_id "testscorm727"
194 192             #}
195 193
196 194             set returndata "cmi.core.student_id=$student_id,cmi.core.student_name=$name,"
197 195             append returndata "cmi.core.lesson_status=$lesson_status,cmi.core.credit=credit,cmi.core.entry=ab-initio,"
198 196             append returndata "cmi.core.lesson_mode=normal,"
199 197             append returndata "cmi.student_preference.language=italian,cmi.comments=$comments,cmi.comments_from_lms=$comments_from_lms"
200 198             append returndata ",cmi.suspend_data=$suspend_data,cmi.launch_data=$launch_data"
201 199             append returndata ",cmi.student_data.max_time_allowed=$maxtimeallowed,cmi.student_data.timelimitaction=$timelimitaction"
202 200             append returndata ",cmi.student_data.mastery_score=$masteryscore"
203 201         } else {
204               ns_log $basiclevel "Huh?SCORM found RTE lorsm_cmi_core: id $currenttrackid"
  202             ns_log $basiclevel "SCORM found RTE lorsm_cmi_core: id $currenttrackid"
205 203             ad_set_client_property lorsm currenttrackid $currenttrackid
206 204             #retrieve data other than core
207 205
208 206             if { ![db_0or1row get_adlcp_student_data2 {}] } {
209 207                 ns_log Error "SCORM recoverying of student data: not successfull on $currenttrackid -> please check"
210 208                 set max_time_allowed ""
211 209                 set time_limit_action ""
212 210                 set mastery_score ""
213 211             } else {
214 212                 ns_log debug "SCORM recoverying of student data: successfull"
215 213             }
216 214             # THIS CHECK is somehow just a previous bug catcher, shouldn't actually be needed
217 215             #               if { [db_resultrows] == 1 } {
218 216             #                       ns_log debug "SCORM recoverying of student data: successfull"
219 217             #                       } else {
220 218             #                       ns_log Error "SCORM recoverying of student data: not successfull on $currenttrackid -> please check"
221 219             #                   }
222 220
223               ns_log $basiclevel "Huh?SCORM retrieved track id in lorsm_cmi_core: $currenttrackid"
  221             ns_log $basiclevel "SCORM retrieved track id in lorsm_cmi_core: $currenttrackid"
224 222             # summing up session time to total_time
225 223             set total_time [expr $total_time + $session_time]
226 224             set total_time_ms [expr $total_time_ms + $session_time_ms]
227 225             set session_time 0
228 226             set session_time_ms 0
229 227
230 228             if { $total_time_ms > 100 } {
231 229                 set total_time_ms [expr $total_time_ms - 100]
232 230                 set total_time [expr $total_time +1 ]
233 231             }
234 232             # erasing session time from server and updating current total time
235 233             set todo "UPDATE lorsm_cmi_core SET total_time = '$total_time"
236 234             append todo "', total_time_ms ='$total_time_ms' "
237 235             #append todo " WHERE track_id=:currenttrackid"
238 236             append todo " WHERE track_id=$currenttrackid"
239 237             db_dml todo $todo
240 238
241 239             if { [db_resultrows] == 1 } {
242 240                 ns_log debug "SCORM time processing UPDATE: '$todo' successfull"
243 241             } else {
 
301 299         if { [ string length $total_time_ms] == 1 } {
302 300             set total_time_ms "$prefix$total_time_ms"
303 301         }
304 302
305 303         if { [ string length $hours ] == 1 } {
306 304             set hours "$prefix$hours"
307 305         }
308 306
309 307         if { [ string length $minutes] == 1 } {
310 308             set minutes 0$minutes
311 309         }
312 310
313 311         if { [ string length $seconds] == 1 } {
314 312             set seconds 0$seconds
315 313         }
316 314
317 315         set total_time "$hours:$minutes:$seconds.$total_time_ms"
318 316         #if { ! [empty_string_p $total_time_ms] } { append total_time ".$total_time_ms" }
319 317         #appending time fields to return string
320 318         append returndata ",cmi.core.session_time=$session_time,cmi.core.total_time=$total_time"
321           ns_log $basiclevel "Huh?SCORM initialised, sending data to applet"
322           ns_log $tracelevel "Huh?$returndata"
  319         ns_log $basiclevel "SCORM initialised, sending data to applet"
  320         ns_log $tracelevel "$returndata"
323 321
324 322         ns_return 200 text/plain "$returndata"
325 323
326 324     } cmiputcat* {
327           ns_log $tracelevel "Huh?---------------------------------------"
  325         ns_log $tracelevel "---------------------------------------"
328 326         switch $functionCalled {
329 327             cmiputcat {
330                   ns_log $basiclevel "Huh?        LMSCommit"
  328                 ns_log $basiclevel "        LMSCommit"
331 329
332 330             } cmiputcatONFINISH {
333                   ns_log $basiclevel "Huh?        LMSFinish"
  331                 ns_log $basiclevel "        LMSFinish"
334 332             }
335 333         }
336           ns_log $tracelevel "Huh?---------------------------------------"
337           ns_log $tracelevel "Huh?received data $data from applet: processing. "
338           ns_log $tracelevel "Huh?Reference cmi track is $currenttrackid, while lorsmstudenttrack is: $lorsmstudenttrack"
  334         ns_log $tracelevel "---------------------------------------"
  335         ns_log $tracelevel "received data $data from applet: processing. "
  336         ns_log $tracelevel "Reference cmi track is $currenttrackid, while lorsmstudenttrack is: $lorsmstudenttrack"
339 337         set preparselist [lrange [ split $data "," ] 1 end]
340 338         set lista [list]
341 339         set value ""
342 340         #here we build a list of request=value. we must do some pattern matching
343 341         foreach couple $preparselist {
344 342             if { [ regexp ^cmi\.* $couple ] } {
345 343                 if { ! [empty_string_p $value]  } {
346 344                     set value [concat [lindex $lista end],$value]
347 345                     ns_log debug "SCORM PARSER ending recomposing $value "
348 346                     set lista [lreplace $lista end end $value]
349 347                     set value ""
350 348                 } else {
351 349                     ns_log debug "SCORM PARSER full couple $couple "
352 350                     lappend lista $couple
353 351                 }
354 352             } else {
355 353                 ns_log debug "SCORM PARSER partial couple $couple "
356 354                 set value [concat $value,$couple]
357 355                 ns_log debug "SCORM PARSER partial couple $couple "
358 356             }
 
461 459                     }
462 460
463 461                 } default {
464 462                     ns_log Warning "SCORM table: '$table', '$column' not implemented -> not treating this applet request"
465 463                 }
466 464             }
467 465         }
468 466
469 467         switch $functionCalled {
470 468             cmiputcat {
471 469                 #We try setting track exit so that we keep some exit time
472 470                 #even if user closes the course without passing by FINISH
473 471                 if { $lorsmstudenttrack == "" || $lorsmstudenttrack == 0 } {
474 472                     lorsm::track::exit -track_id $currenttrackid
475 473                 } else {
476 474                     #speficic for courses for which istrackable is on
477 475                     lorsm::track::exit -track_id $lorsmstudenttrack
478 476                 }
479 477
480 478                 ns_return 200 text/plain "OK"
481                   ns_log $basiclevel "Huh?SCORM post LMSCommit (trackid=$currenttrackid)"
  479                 ns_log $basiclevel "SCORM post LMSCommit (trackid=$currenttrackid)"
482 480
483 481             } cmiputcatONFINISH {
484 482                 set lorsmstudenttrack [ad_get_client_property lorsm studenttrack]
485 483                 ad_set_client_property lorsm studenttrack ""
486 484                 ad_set_client_property lorsm currenttrackid ""
487 485                 ad_set_client_property lorsm initedonpage ""
488 486
489 487                 if { $lorsmstudenttrack == "" || $lorsmstudenttrack == 0 } {
490 488                     lorsm::track::exit -track_id $currenttrackid
491 489
492 490                 } else {
493 491                     #speficic for courses for which istrackable is on
494 492                     lorsm::track::exit -track_id $lorsmstudenttrack
495 493                 }
496 494                 ns_return 200 text/plain "OK"
497                   ns_log $basiclevel "Huh?SCORM post LMSFinish (trackid=$currenttrackid) sent ok to applet"
  495                 ns_log $basiclevel "SCORM post LMSFinish (trackid=$currenttrackid) sent ok to applet"
498 496             }
499 497         }
500 498
501 499     } default {
502 500         #returning a BAD REQUEST and not a GATEWAY ERROR !!!
503 501         ns_return 400 text/plain "Error=103,ErrorDescription=\"No functionCalled meaningful value provided\""
504 502     }
505 503 }
506   ns_log $tracelevel "Huh?---------------------------------------"
507   ns_log $basiclevel "Huh?        LMS Rte server END"
508   ns_log $tracelevel "Huh?---------------------------------------"
  504 ns_log $tracelevel "---------------------------------------"
  505 ns_log $basiclevel "        LMS Rte server END"
  506 ns_log $tracelevel "---------------------------------------"