!
! This will test the HttpResource timout qualifier for Bug 1275 & Bug 1810.
! This is the wrapper portion of the test case (run this to test fix)
!
! @param httpPort  Port for HTTP Server to listen on.
!                  Since NeXtMidas 2.7.0, use 0 to listen on any available port.
! @param delayTime Time in seconds to delay before server sends response back to client
! @param portLabel Results label to save HTTP Server's port in parent's results table
!                  if not blank (e.g. "")
!
! @param httpPort  Port for HTTP server to listen on. Use 0 to listen on any available port.
! @param delayTime Time in seconds for HTTP server to delay before sending a response back to client
!
! @bug 1275 HttpResource: Need to be able to set HTTP timeout via a qualifier
! @bug 1810 CONVERT: default behavior of convert with tbl2xml (output to HttpResource)
! @bug 2253 HTTPSERV: should return 206 (Partial Content) and Content-Range header
! @bug 2254 HttpResource: add ability to get HTTP server's response headers
! @author  Jim Roush - original version
! @author  Neon Ngo - cleanup and mods to listen on any available port, test for Bug 1810
!
startmacro L:hPort[0] L:delay[3]
  switch VERBOSE verbose GET DEF=false SDEF=true

  call setDatDir

  set timeoutExpected false
  set twiceDelay      delay*2
  set halfDelay       delay/2
  ! following 3 results are for testing Bug 1810
  set serverTestResults {got_post=false}
  set t:testdata      {A=1,B=2,NMVER=^env.nmversion}
  convert testdata TBL2XML/S expectedResultsForServer

  ! HTTP POST support was added to HTTPSERV in 2.7.0 (but b/c of Bug 1810,
  ! HttpResource submits a HTTP PUT request)
  invoke HTTPSERV_POST_SUPPORT nxm.sys.lib.StringUtil.compareVersions("^env.nmversion","2.7.0")

  ! start HTTP server for testing HttpResource (in background)
  %test_http_resource_server/bg/id=hresource hPort delay hPort serverTestResults expectedResultsForServer
  ! pause quarter second to give time for sub-macro to launch HTTPSERV
  pause 0.25
  set url "http://localhost:^hPort/httpresource/test.cgi?"

  ! test BUG 2253 and BUG 2254
  call testServerResponseHeaders

  ! test that this HTTP GET request does NOT timeout (since timeout is twice what server is set to)
  if verbose then INFO "Making http resource request with timeout qualifier set to ^{twiceDelay} seconds"
  ! using convert command to generate httpget to server.
  convert ^{url}{timeout=^{twiceDelay}} xml2tab httpresult1
  assert/text="^reg.main.name: HTTP Resource ^{twiceDelay} seconds timeout test done" httpresult1 REXISTS

  ! test that this HTTP GET request timeouts (since timeout is half what server is set to)
  if verbose then INFO "Making http resource request with timeout qualifier set to ^{halfDelay} seconds."
  SET timeoutExpected true
  convert ^{url}{timeout=^{halfDelay}} xml2tab httpresult2
  assert/text="^reg.main.name: HTTP Resource ^{halfDelay} seconds timeout test done" httpresult2 NREXISTS

  ! test for Bug 1810 CONVERT: default behavior of convert with tbl2xml
  if HTTPSERV_POST_SUPPORT GE 0 then
    convert testdata TBL2XML ^{url}{timeout=^{twiceDelay},exist=NONE}
    assert/text="^reg.main.name: HTTP Resource sent POST request for output" serverTestResults.got_post isTrue
  endif

  ! test of issue NXM-3118 HttpResource Incorrectly parsing out password when https://....
  call testParsePasswordFromUrl

  ! test URL containing a query and a fragment
  call testUrlWithQueryAndFragment

  ! send message to stop httpserv
  message FUNC=sendw ID=hresource NAME=STOP_TEST INFO=0 DATA={}
endmacro

procedure processException m:emsg
  if verbose then say "Got exception: emsg=^emsg name=^emsg.name info=^emsg.info data=^emsg.data"
  if timeoutExpected then
    SET timeoutExpected false  ! reset
    assert/text="^reg.main.name: HTTP Resource got timeout" "Read timed out" SUBS emsg.data.toString
  else
    assert/text="^reg.main.name: HTTP Resource unexpected exception: ^emsg.data" FALSE
  endif
return

!******************************************************************************!
! Set the dat directory
!******************************************************************************!
procedure setDatDir
  invoke nxmMajor env.nmversion.subString(0,1)
  invoke major java.lang.Integer.valueOf(nxmMajor)
  if major GE 4 then
    invoke s:datDir           nxm.sys.test.DatLocator.getDatDirLocation()
    invoke s:datDirSlash      nxm.sys.test.DatLocator.getDatDirSlashLocation()
    invoke z:sysDatFull       nxm.sys.test.DatLocator.sysDatFull()
    invoke z:sysTestDatExists nxm.sys.test.DatLocator.sysTestDatExists()
  else
    set s:datDir           "nxm.sys.dat"
    set s:datDirSlash      "nxm/sys/dat"
    set z:sysDatFull       true
    set z:sysTestDatExists false
  endif
return

!******************************************************************************!
! test Bug 2254 (ability to retrieve HTTP response header)
! test Bug 2253 (1. status code is 206 (Partial Content)
!                2. "Content-Range" header is in response
!                3. "Server" header is in response )
! NOTE: if we add support for HTTP resource caching (then we will need a way
!       to disable caching for testing #1 and #2)
!******************************************************************************!
procedure testServerResponseHeaders
  set urlToNoExtendedHdrFile "http://localhost:^hPort/Files/^{datDir}.test1000.prm"
  set urlToExtendedHdrFile "http://localhost:^hPort/Files/^{datDir}.test6000.prm"

  ! test simple case for Bug 2254
  file open tag urlToNoExtendedHdrFile
  res respHeaders0 tag.io.responseheaders
  assert/text="^reg.main.name: HTTP response header: HTTP/1.1 200" respHeaders0.STATUS_LINE EQSS "HTTP/1.1 200"
  table respHeaders0 GETKEY "Server" serverInfo
  assert/text="^reg.main.name: HTTP response header: Server: has NeXtMidas/ver" "NeXtMidas/" EQSS serverInfo
  file close tag

  ! test case for Bug 2253
  file open tag urlToExtendedHdrFile
  res respHeaders tag.io.responseheaders
  assert/text="^reg.main.name: HTTP response header: 206 status code" "206" SUBS respHeaders.STATUS_LINE
  table respHeaders GETKEY "Content-Range" contentRange
  assert/text="^reg.main.name: HTTP response header: Content-Range" "bytes" SUBS contentRange
  file close tag
return

!******************************************************************************!
! test NXM-3118 (HttpResource Incorrectly parsing out password when https://....)
procedure testParsePasswordFromUrl
  new nxm.sys.lib.HttpResource("http://username:password@www.my-site.com")  httpResource
  new nxm.sys.lib.HttpResource("https://username:password@www.my-site.com") httpsResource
  invoke httpURL  httpResource.getURL()
  invoke httpsURL httpsResource.getURL()
  assert/text="^reg.main.name: Password parsed out of HTTP URL"  "http://www.my-site.com"  EQS httpURL
  assert/text="^reg.main.name: Password parsed out of HTTPS URL" "https://www.my-site.com" EQS httpsURL
return

!******************************************************************************!
! test URL containing a query and a fragment
!******************************************************************************!
procedure testUrlWithQueryAndFragment
  new nxm.sys.lib.HttpResource("http://example.com/docs/books/tutorial/index.html?name=networking#DOWNLOADING") httpResource
  invoke httpURL      httpResource.getURLObject()
  invoke httpQuery    httpURL.getQuery()
  invoke httpFragment httpURL.getRef()
  assert/text="^reg.main.name: HTTP Resource URL query"    "name=networking" EQS httpQuery
  assert/text="^reg.main.name: HTTP Resource URL Fragment" "DOWNLOADING"     EQS httpFragment
return