Jump to content
TheXman

HttpApi UDF - HTTP Server API

Recommended Posts

Posted (edited)

http_server.png.5b3d10628ab13edd960229d18570021e.png

Purpose (from Microsoft's website)

The HTTP Server API enables applications to communicate over HTTP without using Microsoft Internet Information Server (IIS). Applications can register to receive HTTP requests for particular URLs, receive HTTP requests, and send HTTP responses. The HTTP Server API includes SSL support so that applications can exchange data over secure HTTP connections without IIS.

Description

There have been several times in the past that I wanted to either retrieve information from one of my PCs or execute commands on one of my PCs, whether it was from across the world or sitting on my couch.  Since AutoIt is one of my favorite tools for automating just about anything on my PC, I looked for ways to make to make it happen.  Setting up a full blown IIS server seemed like overkill so I looked for lighter weight solutions.  I though about creating my own AutoIt UDP or TCP servers but that just wasn't robust enough,  Then I found Microsoft's HTTP Server API and it looked very promising.  After doing a little research into the APIs, I found that it was flexible & robust enough to handle just about any of the tasks that I required now and in the future.  So a while back I decided to wrap the API functionality that I needed into an AutoIt UDF file to allow me to easily create the functionality I needed at the time.  It has come in very handy over the years.  Of course it wasn't all wrapped up with a nice little bow like it is now.  That only happened when I decided to share it with anyone else who could use it or learn from it.

The example file that I included is a very granular example of the steps required to get a lightweight HTTP Server up and listening for GET requests.  The UDF is a wrapper for the Microsoft APIs.  That means to do anything over and above what I show in the example, one would probably have to have at least a general knowledge of APIs or the ability to figure out which APIs/functions to use, what structures and data is needed to be passed to them, and in what order.  However, the UDF gives a very solid foundation on which to build upon.  Of course, if anyone has questions about the UDF or how to implement any particular functionality, I would probably help to the extent that I could or point you in the right direction so that you can figure out how to implement your own solution.

Being that this is basically an AutoIt wrapper for the Microsoft API functions, there's no need to create AutoIt-specific documentation.  All of the UDF functions, structures, constants, and enumerations are named after their Microsoft API counterparts.  Therefore, you can refer to Microsoft's extensive documentation of their HTTP Server API.

The APIs included in the UDF are the only ones that I have needed in the past to do what I needed to do.  If you would like any additional APIs to be added to the UDF file, please suggestion them.

Related Links

Microsoft HTTP Server API - Start Page
Microsoft HTTP Server API - API v2 Reference
Microsoft HTTP Server API - Programming Model

 

 

>>> See screen shots and DOWNLOAD in the Files section <<<

 

Edited by TheXman

Share this post


Link to post
Share on other sites

Nice example. It does not work running as x86 ( is there a reason?).

 

Saludos

Share this post


Link to post
Share on other sites

I did a small check and seems to be calls need to be stdcall. also there is an issue HttpSendHttpResponse maybe some structure is not compatible.

 

Saludos

Share this post


Link to post
Share on other sites
Posted (edited)

It appears that when running in a WOW64 environment, running as a 32-bit app on a 64-bit OS, the DllCall functions get corrupted.  In pure 64-bit, the cdecl calling convention is used.  Could it be that stdcall is necessary in WOW64?

When I compile the app as x64, everything appears to work fine.  When I compile as x86, I get the following error after the first dllcall:

image.png.dc02263080994e6fb08d93eba99365c9.png

Edited by TheXman

Share this post


Link to post
Share on other sites
Posted (edited)
3 minutes ago, Danyfirex said:

there is an issue HttpSendHttpResponse

Is this when running x64?  If so, can you give me steps to recreate the issue?

Edited by TheXman

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

I just created a 2nd version of the httpapi.au3 file, called httpapi_x86.au3 that removes all of the references to ":cdecl", which changes the calls to stdcall. When using it in a wow64 environment, it works better but as you stated, HttpSendHttpResponse has an issue.  I will look at the parameters to see where there error is happening. 

It looks like I will need to create a slightly modified version of the UDF for x86 environments.

Thanks for finding and reporting this issue.  I should have it resolved in a bit.  :thumbsup:

 

Share this post


Link to post
Share on other sites

I've found what I think is the issue, which are the _declspec declarations on the C++ functions.  Now I just have to figure out how I'm going to resolve it in AutoIt.

Share this post


Link to post
Share on other sites

For now, I have uploaded a new version (v1.0.1), that includes a directive to force the example to run as x64 mode. 

I have also changed all of the API DllCalls from cdecl to stdcall.  I tested the change when running as x64 on a x64 OS and it appears to work fine.

Hopefully, I will be able to figure out a way to have the code run successfully as x86 on a x64 OS soon.  As I mentioned in the Files section, I don't have a x86 OS PC to test on to see whether it runs fine as x86 on a x86 OS or whether this is a WOW64 issue.

Share this post


Link to post
Share on other sites

I was compiling to x86 and running in x64 machine. Is where I saw the issue. I think if it work compiling as x86 would probably work correctly running in a x86 OS.

I'll review later. When I'm in from of computer.

Saludos

Share this post


Link to post
Share on other sites
1 minute ago, argumentum said:

WOW, you always with cool stuff  

Thanks! :D

2 minutes ago, argumentum said:

Can you show an example of SSL usage ?.

Yes.  As soon as I figure out the little issue I'm having with it being able to run in a WOW64 environment, I will post detailed steps on how to enable SSL.  Basically, the easiest way to do it would be to import your SSL certificate (self-signed or from a real CA) into the correct certificate store and then execute the netsh command to register that cert with the URL that you are using. 

https://docs.microsoft.com/en-us/windows/win32/http/add-sslcert

 

Share this post


Link to post
Share on other sites
14 minutes ago, argumentum said:

Edit: ..ok, a next version will add HttpSetServiceConfiguration()

Yes, as you figured out, you can also do it using the API.  :)

Share this post


Link to post
Share on other sites
Posted (edited)

Hello. I checked deeply. The issue in x86 mode is in the $__HTTPAPI_gtagHTTP_DATA_CHUNK_FROM_MEMORY structure.

 

I just patched it with this. (I didn't want to look into that messed union structure🤣)

Global $__HTTPAPI_gtagHTTP_DATA_CHUNK_FROM_MEMORY = _
           $__HTTPAPI_gtagHTTP_DATA_CHUNK         & _
           "struct;"                              & (@AutoItX64 ? "" : "ptr;") & _
           "ptr    pBuffer;"                      & _
           "ulong  pBufferLength;"                & _
           "endstruct;"

 

It also works running under x86 OS. (Tested in Windows 7x86)

 

Saludos

Edited by Danyfirex

Share this post


Link to post
Share on other sites

@Danyfirex

You are awesome:thumbsup:

I kept trying to find the issue last night until I couldn't keep my eyes open any longer and just fell asleep.  Then I woke up this morning and saw your post.  I felt like a little kid on Christmas morning seeing all the gifts under the tree,  :cheer:

I'm going to put your fix in and post a new version now (or as soon as I can get a cup of coffee in me). :)

Your efforts are greatly appreciated!

Share this post


Link to post
Share on other sites

HttpApi UDF v1.1.1 was just published to the Files section.

  • v1.1.1 (2020-05-31)
    • Optimized the fix made by @Danyfirex so that it works for all of the union'd DATA_CHUNK structs.

Share this post


Link to post
Share on other sites
Posted (edited)

@argumentum

As promised, here are the steps to enable the example script to listen and respond to HTTPS requests using a simple NETSH command.

  1. First, I would suggest that you change the listening URL path in the example from a host name to an IP address.  It makes everything a lot easier.  Doing a Replace All from "localhost" to "127.0.0.1" in the example should do the trick.
     
  2. Change the global constant $HTTP_HOST's protocol from "http" to "https". Save or "Save As" the changes to the example script.  That's all that needs to be changed in the script.
     
  3. Next, you need import a SSL certificate into the Local Machine's "Personal" key store.  Make sure it is in the Local Machine hive, not the Current User.  As I'm sure you already know, you can do this by either running the certmgr.msc MMC plugin or right-clicking the file and selecting "Install PFX".  The imported SSL cert must contain the key.  So you will most likely need to have a .p12 or .pfx file to easily import it.
     
  4. The last step is to "bind" the IP:Port combination to the SSL certificate in the Local Machine's Personal key store.  To do this, you need to make a note of the SSL certificate's thumbprint hash.  If it was hashed with SHA-1, it will be a 20 hex bytes (40 char hex string).  This will be needed by the NETSH command that follows.  Execute the following command:

    netsh http add sslcert ipport=127.0.0.1:9000 certhash=<thumbprint hash> appid={<GUID>}

    example:
    netsh http add sslcert ipport=127.0.0.1:9000 certhash=84c6501539603c1b131fec8695c886227b0363a5 appid={CC305314-5579-44BF-BCD2-180FE2DB2BD2}

    The appid GUID can be any valid GUID.  I just used the AutoIt3 _WinAPI_CreateGUID function to generate one.  If the command is successful, you will see a message saying that the cert was added.  Otherwise, you will probably see a message simply saying "Invalid parameter".  The binding of the ip:port to the certificate is persistent.  The entry will stay until it is deleted.

 

That's it!  If everything went well, you should be able to start your http server and access it in your browser using https.  If you run into any issues, just let me know and I'll help you get it resolved.

Edited by TheXman

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...