Sending a HTML form using a C++ console application?

SineCosine

I'm still looking for my Tangent
Reaction score
77
Umm..
I've been googling for days now, (Maybe even months, never kept track) and haven't found an answer to my question.

You know those HTML forms that you submit with the click of a button after filling in a variety of text-fields?

How would one send those HTML forms using C++?
As in, no need to open a browser.

Googling only ever got me vague explanations of what sockets are and that I'd be needing them.
But nothing put in layman terms =x

If anyone could spare some time to tell me what libraries I'd need along with some guidance.. I'd be grateful :D
 

SineCosine

I'm still looking for my Tangent
Reaction score
77
I just got back home =)
Umm..
Forgive me if this sounds stupid, but..

Code:
#include <fstream>
 
#include <cstdlib>
#include <cerrno>
 
#include <curlpp/curlpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>
 
int main(int argc, char *argv[])
{
  if(argc < 2) {
    std::cerr << argv[0] << ": Wrong number of arguments" << std::endl 
        << "Usage: " << argv[0] << " url"
        << std::endl;
    return EXIT_FAILURE;
  }
 
  char *url = argv[1];
 
  try {
    curlpp::Cleanup cleaner;
    curlpp::Easy request;
 
    request.setOpt(new curlpp::options::Url(url)); 
    //request.setOpt(new curlpp::options::Verbose(true)); 
 
    {
      // Forms takes ownership of pointers!
      curlpp::Forms formParts;
      formParts.push_back(new curlpp::FormParts::Content("name1", "value1"));
      formParts.push_back(new curlpp::FormParts::Content("name2", "value2"));
 
      request.setOpt(new curlpp::options::HttpPost(formParts)); 
    }
 
    // The forms have been cloned and are valid for the request, even
    // if the original forms are out of scope.
    std::ofstream myfile("/dev/null");
    myfile << request << std::endl << request << std::endl;
  }
  catch ( curlpp::LogicError & e ) {
    std::cout << e.what() << std::endl;
  }
  catch ( curlpp::RuntimeError & e ) {
    std::cout << e.what() << std::endl;
  }
 
  return EXIT_SUCCESS;
}

This part:
int main(int argc, char *argv[])
Umm..
How are you allowed to pass arguments to the main function?
Isn't it, like, the first function that's run when you run an application?
How do you pass arguments to a function that is run immediately?

[EDIT]
Ugh, I can't do it.
I can't seem to compile/build libcurl using Microsoft Visual C++ 2008 Express.

So.. many.. errors..
So.. many.. different googled tutorials..
Nothing for Microsoft Visual C++ 2008 Express =/

[EDIT=2]
Code:
1>------ Build started: Project: libcurl, Configuration: Debug Win32 ------
1>Compiling...
1>stdafx.cpp
1>libcurl.cpp
1>Generating Code...
1>Linking...
1>libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_cleanup referenced in function _main
1>libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_perform referenced in function _main
1>libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_setopt referenced in function _main
1>libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_init referenced in function _main
1>C:\MyFirstAttempt\libcurl\Debug\libcurl.exe : fatal error LNK1120: 4 unresolved externals
1>Build log was saved at "file://c:\MyFirstAttempt\libcurl\libcurl\Debug\BuildLog.htm"
1>libcurl - 5 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Code:
Build Log      Build started: Project: libcurl, Configuration: Debug|Win32
 Command Lines      Creating temporary file "c:\MyFirstAttempt\libcurl\libcurl\Debug\RSP00002F10121884.rsp" with contents
[
/Od /I "C:\MyFirstAttempt\libcurl\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /c /ZI /TP .\libcurl.cpp

.\stdafx.cpp
]
Creating command line "cl.exe @c:\MyFirstAttempt\libcurl\libcurl\Debug\RSP00002F10121884.rsp /nologo /errorReport:prompt"
Creating temporary file "c:\MyFirstAttempt\libcurl\libcurl\Debug\RSP00003010121884.rsp" with contents
[
/OUT:"C:\MyFirstAttempt\libcurl\Debug\libcurl.exe" /INCREMENTAL /LIBPATH:"C:\MyFirstAttempt\libcurl" /MANIFEST /MANIFESTFILE:"Debug\libcurl.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\MyFirstAttempt\libcurl\Debug\libcurl.pdb" /SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT /MACHINE:X86 C:\MyFirstAttempt\libcurl\lib\libcurl.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

".\Debug\stdafx.obj"

".\Debug\libcurl.obj"

".\Debug\libcurl.exe.embed.manifest.res"
]
Creating command line "link.exe @c:\MyFirstAttempt\libcurl\libcurl\Debug\RSP00003010121884.rsp /NOLOGO /ERRORREPORT:PROMPT"
 Output Window      Compiling...
stdafx.cpp
libcurl.cpp
Generating Code...
Linking...
libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_cleanup referenced in function _main
libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_perform referenced in function _main
libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_setopt referenced in function _main
libcurl.obj : error LNK2019: unresolved external symbol __imp__curl_easy_init referenced in function _main
C:\MyFirstAttempt\libcurl\Debug\libcurl.exe : fatal error LNK1120: 4 unresolved externals
 Results      Build log was saved at "file://c:\MyFirstAttempt\libcurl\libcurl\Debug\BuildLog.htm"
libcurl - 5 error(s), 0 warning(s)

[EDIT=3]
That came across wrongly, I can build it, I do have the .lib and .dll files along with the include folder from building it.
But I can't figure out how to make VC++ 2008 include those files in a project so that I can use the functions =/

The more I google, the bigger my headache gets >.<
 

celerisk

When Zerg floweth, life is good
Reaction score
62
" unresolved external symbol "

You didn't tell the linker to include the library.
Project > Configuration / Settings / Properties (or something similar) > Linker > Command line?
(Or something vaguely looking like it. Ages since I last used VC)



" ... using a C++ console application "

Ehm... you're building a console application and never used the console?
Well, open a "command prompt".
Use "cd" (with tab if you are too lazy to type) to navigate to the folder your program is in.
Type the name and add whatever parameters you want.

Something like this:
C:\> cd /users/celerisk/My Documents/Development/my project/
program-name parameter1 parameter2 ...

Or create a shortcut to it, edit its properties and add them after the "target".
 

SineCosine

I'm still looking for my Tangent
Reaction score
77
I could have sworn I did tell it to include it.. *Scratches head*
I've only ever learned to play around with:

cin, cout, getline, stringstream, variables, etc. xD
I don't know any of the.. Erm..
C++ natives (I think you call them that, like, opening a file, creating one, read from one, forcing a global key press, detecting a keypress, etc.)

I did it for the include and library paths..
Is there anything else I'd need to add? o.0

[EDIT]
This is what I entered for: Additional Include Directories
Code:
"C:\MyFirstAttempt\curl-7.21.0\include\curl";"C:\MyFirstAttempt\curl-7.21.0\include"

This is what I entered for: Additional Library Directories
Code:
"C:\MyFirstAttempt\curl-7.21.0\lib\DLL-Debug";"C:\MyFirstAttempt\curl-7.21.0\lib\LIB-Debug";"C:\MyFirstAttempt\curl-7.21.0\lib"

[EDIT=2]
Wait-
You were right:
Project > Configuration / Settings / Properties (or something similar) > Linker > Command line
I didn't add libcurl.lib =x

But after adding it..
I got 69 errors =x

Code:
1>------ Build started: Project: TestCURL, Configuration: Debug Win32 ------
1>Linking...
1>libcurl.lib(easy.obj) : error LNK2019: unresolved external symbol __imp__WSACleanup@0 referenced in function _win32_init
1>libcurl.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__WSACleanup@0
1>libcurl.lib(easy.obj) : error LNK2019: unresolved external symbol __imp__WSAStartup@8 referenced in function _win32_init
1>libcurl.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__WSAStartup@8
1>libcurl.lib(ftp.obj) : error LNK2001: unresolved external symbol __imp__closesocket@4
1>libcurl.lib(http.obj) : error LNK2001: unresolved external symbol __imp__closesocket@4
1>libcurl.lib(url.obj) : error LNK2019: unresolved external symbol __imp__closesocket@4 referenced in function _conn_free
1>libcurl.lib(transfer.obj) : error LNK2001: unresolved external symbol __imp__closesocket@4
1>libcurl.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__closesocket@4
1>libcurl.lib(hostthre.obj) : error LNK2001: unresolved external symbol __imp__closesocket@4
1>libcurl.lib(tftp.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
1>libcurl.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
1>libcurl.lib(ftp.obj) : error LNK2019: unresolved external symbol __imp__WSAGetLastError@0 referenced in function _ftp_parse_url_path
1>libcurl.lib(select.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
1>libcurl.lib(transfer.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
1>libcurl.lib(sendf.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
1>libcurl.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
1>libcurl.lib(hostthre.obj) : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
1>libcurl.lib(sendf.obj) : error LNK2019: unresolved external symbol __imp__send@16 referenced in function _Curl_send_plain
1>libcurl.lib(telnet.obj) : error LNK2001: unresolved external symbol __imp__send@16
1>libcurl.lib(sendf.obj) : error LNK2019: unresolved external symbol __imp__recv@16 referenced in function _Curl_recv_plain
1>libcurl.lib(connect.obj) : error LNK2001: unresolved external symbol __imp__recv@16
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__getsockname@12 referenced in function _Curl_updateconninfo
1>libcurl.lib(ftp.obj) : error LNK2001: unresolved external symbol __imp__getsockname@12
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__getpeername@12 referenced in function _Curl_updateconninfo
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__ntohs@4 referenced in function _getaddressinfo
1>libcurl.lib(ftp.obj) : error LNK2001: unresolved external symbol __imp__ntohs@4
1>libcurl.lib(socks.obj) : error LNK2001: unresolved external symbol __imp__ntohs@4
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__getsockopt@20 referenced in function _verifyconnect
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__setsockopt@20 referenced in function _Curl_sndbufset
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__connect@12 referenced in function _singleipconnect
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__socket@12 referenced in function _singleipconnect
1>libcurl.lib(hostthre.obj) : error LNK2001: unresolved external symbol __imp__socket@12
1>libcurl.lib(ftp.obj) : error LNK2001: unresolved external symbol __imp__socket@12
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__bind@12 referenced in function _bindlocal
1>libcurl.lib(tftp.obj) : error LNK2001: unresolved external symbol __imp__bind@12
1>libcurl.lib(ftp.obj) : error LNK2001: unresolved external symbol __imp__bind@12
1>libcurl.lib(connect.obj) : error LNK2019: unresolved external symbol __imp__htons@4 referenced in function _bindlocal
1>libcurl.lib(curl_addrinfo.obj) : error LNK2001: unresolved external symbol __imp__htons@4
1>libcurl.lib(ftp.obj) : error LNK2001: unresolved external symbol __imp__htons@4
1>libcurl.lib(socks.obj) : error LNK2001: unresolved external symbol __imp__htons@4
1>libcurl.lib(curl_addrinfo.obj) : error LNK2019: unresolved external symbol __imp__freeaddrinfo@4 referenced in function _Curl_getaddrinfo_ex
1>libcurl.lib(curl_addrinfo.obj) : error LNK2019: unresolved external symbol __imp__getaddrinfo@16 referenced in function _Curl_getaddrinfo_ex
1>libcurl.lib(smtp.obj) : error LNK2019: unresolved external symbol __imp__gethostname@8 referenced in function _smtp_connect
1>libcurl.lib(tftp.obj) : error LNK2019: unresolved external symbol __imp__sendto@24 referenced in function _tftp_send_first
1>libcurl.lib(tftp.obj) : error LNK2019: unresolved external symbol __imp__recvfrom@24 referenced in function _tftp_receive_packet
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_unbind_s referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_msgfree referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ber_free referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_memfree referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_value_free_len referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_get_values_len referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_next_attribute referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_first_attribute referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_get_dn referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_next_entry referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_first_entry referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_search_s referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_simple_bind_s referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_init referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_set_option referenced in function _Curl_ldap
1>libcurl.lib(ldap.obj) : error LNK2019: unresolved external symbol __imp__ldap_err2string referenced in function _Curl_ldap
1>libcurl.lib(ftp.obj) : error LNK2019: unresolved external symbol __imp__listen@8 referenced in function _ftp_state_use_port
1>libcurl.lib(ftp.obj) : error LNK2019: unresolved external symbol __imp__accept@12 referenced in function _AllowServerConnect
1>libcurl.lib(select.obj) : error LNK2019: unresolved external symbol ___WSAFDIsSet@8 referenced in function _Curl_socket_ready
1>libcurl.lib(select.obj) : error LNK2019: unresolved external symbol __imp__select@20 referenced in function _Curl_socket_ready
1>libcurl.lib(select.obj) : error LNK2019: unresolved external symbol __imp__WSASetLastError@4 referenced in function _wait_ms
1>libcurl.lib(nonblock.obj) : error LNK2019: unresolved external symbol __imp__ioctlsocket@12 referenced in function _curlx_nonblock
1>C:\MyFirstAttempt\curl-7.21.0\TestCURL\Debug\TestCURL.exe : fatal error LNK1120: 42 unresolved externals
1>Build log was saved at "file://c:\MyFirstAttempt\curl-7.21.0\TestCURL\Debug\BuildLog.htm"
1>TestCURL - 69 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I know I'm definitely missing some dll or lib file this time, too.
Since the error messages are about the same.
Just.. In larger quantities now =/
 

celerisk

When Zerg floweth, life is good
Reaction score
62
WSA... and friends means a missing socket library.
ws2_32.lib (I think... google it :D)

For the "ldap" errors: wldap32.lib (probably) - what you need ldap for?
 

SineCosine

I'm still looking for my Tangent
Reaction score
77
Holy ****
Adding those 2 libraries solved all 69 errors ._.
How do you remember all this?

You must've spent at least 5 lifetimes programming O_O
I am awed again.

[EDIT]
I'm now reading up on all the functions libcurl has <.<
What's the difference between curl_easy_init() and curl_share_init() ?
Also, it returns.. what exactly?

A.. CURL *handle?
Is it an instance of a connection or something like that? o.0

[EDIT=2]
Any idea why this won't work?
Yea, I'm just playing around with it for now =x
Code:
// TestCURL.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <curl.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>

using namespace std;

int main () {
  CURL *curl;
  CURLcode res;
  string test;
  
  cout<< "Enter a Web Address: ";
  getline(cin, test);
 
  curl = curl_easy_init();
  if(curl) {
	  curl_easy_setopt(curl, CURLOPT_URL, test); //This does not work.
    res = curl_easy_perform(curl);
 
    /* always cleanup */ 
    curl_easy_cleanup(curl);
  }
  return 0;

}

[EDIT=3]
Yessah!
Woot!

Celerisk!
You've done it again!
You helped me out BIG TIME!
YESSAH!!!

It worked!
WORKED!!!!

I am happyyyyyyyy~~~
Now I need to figure out how to read and write from a text file -____-

[EDIT]
The form was sent with libcurl!
La dee da!!!
This feels gooooood
 

celerisk

When Zerg floweth, life is good
Reaction score
62
" Is it an instance of a connection "

Close enough.

From your example:
curl_easy_setopt(curl, CURLOPT_URL, test)

This adds "test" as "URL" to "curl".
For this to work, curl needs to be... well, something that makes sense to the library.
That sense comes from the init call.


You noticed that libcurl offers a multi interface?
As the doc puts it:
" Enable multiple simultaneous transfers in the same thread without making it complicated for the application "
 

SineCosine

I'm still looking for my Tangent
Reaction score
77
Transfers.. In the same thread? o.0
You mean multiple "curl_easy_setopt(curl, CURLOPT_URL, parameter)"s at one go?

So.. using..
curl_multi_add_handle(Some *curl easy handle.. )
curl_multi_perform()

???
But curl_easy_setopt does not return any.. handles.
 

SerraAvenger

Cuz I can
Reaction score
234
Just out of interest, why would you ever do something like that in C++?:confused:
Why not ruby/RoR?
I think golang is nice for such stuff too.
 

celerisk

When Zerg floweth, life is good
Reaction score
62
" why would you ever do something like that in C++? "

Speed.
C / C++ is the only guaranteed way to get this to wire-speed :p
And you do want wire-speed on something as significant as spamming unsuspecting Internet users.


Why he is going for it, I do not know.
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
Forget about speed. If your so concerned with speed, code in machine language.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top