Web Connection
Deploy Updates To Multiple Servers
Gravatar is a globally recognized avatar based on your email address. Deploy Updates To Multiple Servers
  Scott R
  All
  Jan 31, 2019 @ 07:28am

Rick / Others,

I saw on https://webconnection.west-wind.com/docs/_s8x08h3ks.htm that you can upload a zip file via the web connection admin page. From there I believe you have to manually connect into the server, extract the files out, and then place them in the correct directory (i.e. data / deploy). Is that correct?

We currently have 3 servers running web connect as a web service. (We need 3 to handle the traffic load.) I'm wondering if there's an easy way to 'mass' publish our update to all three servers? Currently I RDP into each server, copy over a zip file, stop the website in IIS so the files aren't in use, unzip the components to the correct location and then restart IIS.

Is there an easier way to do this? We have an FTP site and I could publish the update / zip folder there but then I'm not sure how to replace the files since my web connect .exe running this process would be shut down since part of the update is to replace the exe. I know that the web connect admin page has an 'upload server exe' and 'update server exe' function but wondering if there's a way to do that where the exe is inside the zip folder along with a few other files I need / how to programatically call that function so I don't have to log in to each individual admin page?

The only other idea I've had is to bring up a second web connect site on each server that is simply an 'update' site for us that I can send a request to that tells it there's an update, it downloads the zip file from our ftp site, stops the main web service site (i.e. via a .bat file that runs as an admin), updates the files, and starts the web site up again for me.

Has anyone done something like this before or have any ideas?

Thanks,

Scott

Gravatar is a globally recognized avatar based on your email address. re: Deploy Updates To Multiple Servers
  Rick Strahl
  Scott R
  Jan 31, 2019 @ 01:20pm

Depends on what you need to do. If you just need to update your main application EXE that's built in via the Update Server functionality. You can do this with DO bld_MyApp.prg or if you want to manually from the Web site. This updates the application's EXE and handles starting/stopping/copying/registering/restarting the server. But it only works for the main EXE.

If you have additional files you need to publish you are on your own. However, you can look at what bld_YourApp.prg does and basically duplicate some of that behavior. You can call remote commands to unload servers and put the servers on hold, update, then bring everything back up. All of those commands on the admin page can be executed via wwHttp::Get() operations.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Deploy Updates To Multiple Servers
  Scott R
  Rick Strahl
  Feb 1, 2019 @ 11:04am

Rick,

This is great. Thanks. However, I am having a problem using the code built in to the bld_myapp.prg. I am able to successfully upload the new exe using your interface on the admin page through the browser but I cannot get it to work using the code in bld_myapp.

My exe is approx 20 mb and so I found on https://webconnection.west-wind.com/docs/_566027hhg.htm where you say to use

loHttp.lUseLargePostBuffer = .T.

and I added

<httpRuntime maxRequestLength="50000000" ... >

I then do the loHttp.get(myUrl) and the problem I'm getting is I get

loHttp.nError = 500
loHttp.cErrorMsg = 'Internal Server Error'

When I look at the lcHTML return from the loHTTP get it says

      <div id="MainView">
        <div class="container">
            <div class="page-header-text">
                <i class="fa fa-gear"></i>
                Missing File
            </div>

            <div>
                It appears that there was no file uploaded.
            </div>
        </div>

So basically I am doing

loHttp = CREATEOBJECT("wwHttp")
oHttp.cUsername = '<<username>>'
loHttp.cPassword = '<<password>>'
loHttp.nHttpPostMode = 2
loHttp.lUseLargePostBuffer = .T. 
loHttp.AddPostKey("File",FULLPATH(EXE_FILE + ".exe"),.T.)
lcHtml = loHttp.HttpGet(HTTP_UPLOADURL)
IF (loHttp.nError != 0) OR ATC("File has been uploaded",lcHtml) = 0
	MESSAGEBOX("Upload failed." + CHR(13) + ;
	                 loHttp.cErrorMsg)
	RETURN
ENDIF

and I am getting the response that there was no file uploaded.

What's slightly wierder is the fact that if I do the exact same thing but with a smaller file (under 16 mb) and get rid of the useLargePost buffer it uploads no problem.

Again, if I upload via the browser / admin page it works perfectly.

Any thoughts?

Thanks,

Scott

Gravatar is a globally recognized avatar based on your email address. re: Deploy Updates To Multiple Servers
  Rick Strahl
  Scott R
  Feb 1, 2019 @ 01:34pm

Hmmm... looks like there's a bug with the large post buffer posting logic - the trailing headers are missing. I think if you publish a smaller file with the .lUseLargePostBuffer option (even though it's not needed) that will fail to.

Here's a fix for it:

In wwHttp.prg find the HttpGetEx() function and scroll down to the large IF block IF !EMPTY(this.cPostBuffer). Replace that code with the following:

LOCAL llHasPostData
llHasPostData = .F.
IF !this.lUseLargePostBuffer
   llHasPostData = !EMPTY(this.cPostBuffer)
ELSE
   IF !ISNULL(this.oPostStream) AND FSEEK(this.oPostStream.nHandle,0,1) > 0
      llHasPostData = .T.
   ENDIF
ENDIF

IF llHasPostData
   ...
ENDIF

This ensures that the appropriate postfix is applied in large post buffer mode.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Deploy Updates To Multiple Servers
  Scott R
  Rick Strahl
  Feb 1, 2019 @ 02:57pm

Rick,

Thanks for fixing this so fast... slight problem. Can't quite tell what you want me to replace... This is the block of code you mentioned:

IF !EMPTY(this.cPostBuffer)
   DO CASE
      *** Explicit content type overrides manual content type
      CASE !EMPTY(this.cContentType)
		 	tcHeaders = "Content-Type: " + this.cContentType + CRLF + tcHeaders      
      CASE THIS.nhttppostmode = 1
         tcHeaders = "Content-Type: application/x-www-form-urlencoded"  + CRLF +;
            IIF(!EMPTY(tcHeaders),CRLF+tcHeaders,"")
      CASE THIS.nhttppostmode = 2
         tcHeaders = "Content-Type: multipart/form-data; boundary=" + MULTIPART_BOUNDARY + CRLF + CRLF +;
            IIF(EMPTY(tcHeaders),"",tcHeaders)

		 *** Add ending content bounda
         *** NOTE: leading and trailing extra two dashes required!
         IF !THIS.lUseLargePostBuffer
			 this.cPostBuffer = this.cPostBuffer +"--" + MULTIPART_BOUNDARY + "--"  + CRLF
		 ELSE			 
			 this.oPostStream.Write("--" + MULTIPART_BOUNDARY + "--"  + CRLF)
		 ENDIF
         
      OTHERWISE      && CASE THIS.nhttppostmode = 4  && XML or Raw
         tcHeaders = "Content-Type: text/xml" + CRLF + tcHeaders		 
   ENDCASE
ELSE
   tcHeaders =  IIF(!EMPTY(tcHeaders),tcHeaders,"")
ENDIF

I'm not sure which part of this you want me to replace, especially since I searched all of wwHTTP and there is nothing with

llHasPostData

and so I'm not sure what to do with your last comment of

IF llHasPostData
   ...
ENDIF

unless I'm using an old version and missing something you're expecting me to have? I am using the version that comes with web connect 6.21...

Thanks,

Scott

Gravatar is a globally recognized avatar based on your email address. re: Deploy Updates To Multiple Servers
  Rick Strahl
  Scott R
  Feb 1, 2019 @ 03:03pm

Replace the IF !EMPTY(this.cPostBuffer) with the block of code I posted (up to the IF not what comes after).

After replacing it should look like this:

DECLARE INTEGER HttpSendRequest    ;
   IN WININET.DLL ;
   INTEGER hHTTPHandle,;
   STRING lpzHeaders,;
   INTEGER cbHeaders,;
   STRING lpzPost,;
   INTEGER cbPost

LOCAL llHasPostData
llHasPostData = .F.
IF !this.lUseLargePostBuffer
   llHasPostData = !EMPTY(this.cPostBuffer)
ELSE
   IF !ISNULL(this.oPostStream) AND FSEEK(this.oPostStream.nHandle,0,1) > 0
      llHasPostData = .T.
   ENDIF
ENDIF

IF llHasPostData
   DO CASE
      *** Explicit content type overrides manual content type
      CASE !EMPTY(this.cContentType)
		 	tcHeaders = "Content-Type: " + this.cContentType + CRLF + tcHeaders      
      CASE THIS.nhttppostmode = 1
         tcHeaders = "Content-Type: application/x-www-form-urlencoded"  + CRLF +;
            IIF(!EMPTY(tcHeaders),CRLF+tcHeaders,"")

...

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Deploy Updates To Multiple Servers
  Rick Strahl
  Scott R
  Feb 1, 2019 @ 03:05pm

Or at this point you can download an updated version of the full Web Connection installer. I've updated the full distribution... Just re-download the registered version with same file/pwd as before.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Deploy Updates To Multiple Servers
  Scott R
  Rick Strahl
  Feb 1, 2019 @ 03:24pm

Rick,

Worked perfectly. Thanks!

© 1996-2019