Upload a file to a web server using C++ - c++

I want to upload files from a client location to a server. At present, I have a client-server socket program by which I could send/receive files across, but I would like to improvise it.
My idea would be to transfer the file using HTTP PUT/POST from client (most of the coding on client side) to the server. Since I have no idea about HTTP programming, so I need some guidance on how to achieve that. I want to use C++ with BSD sockets in doing that, and no other libraries. My aim is to send the server a form, like as given below with a HTTP POST/PUT request, and get the file "main.cpp" uploaded to the server.
PUT http://localhost/ HTTP/1.0
Host: localhost
Content-type: form-data
Content-length: 90
FileUpload: /Users/SG/files/main.cpp
I was able to write a dummy program that does some PUT from a client, and the web server running Apache returns a HTTP 200. What I am failing to understand currently would be the following two things, which I guess are somewhat connected:
How one could specify a file to be uploaded from the client in the form above?
If I understand correctly, the file would be read at client site and then the file content would be sent to the server, where a server side script would read the bytes from client and create a copy of the file at the server. Is it correct?
Any help is appreciated.
Thanks,
Sayan

As stated it's not possible. C++ alone has no sockets API. (Edit: with the addition of a BSD sockets API, it's now possible).
Your implementation might provide an OS-specific sockets API, in which case your question boils down to, "how do I write an HTTP client?". To which the answer is (a) don't, or (b) read the HTTP specification very carefully and do as it tells you. The basic steps are:
(Possibly) parse a URL and use gethostbyname to get an IP address.
Open a TCP socket, using connect.
Write the request (you already have an idea what that looks like) using send.
Read the response using read.
Close the connection.
The difficult part is parsing the response robustly, because there are a lot of features to worry about. If your client is tied to a particular server, then its responses will be quite predictable, and you can ignore quite a lot of the HTTP spec (at least until you change the configuration of the server, update its software, etc).
If you're ready to give up before you finish, there are perfectly good HTTP libraries available, such as libcURL.

I want to use C++ for doing this,
without the help of any libraries or
system() calls.
Socket programming always requires system calls. C++ is an extremely general language. The ISO language definition does not specify anything about sockets or network programming, so in order to do this you need to rely on another system-specific library/standard, such as the BSD socket API on UNIX/Linux. Usually, in C++ you would use a higher-level third-party library that wraps these lower level system calls, such as Boost.ASIO. However, even that takes a bit of learning, to say nothing of correctly implementing the HTTP standard itself on top of your sockets.

I was able to attain what I wanted. My http post request string looks like below:
"POST %s HTTP/1.0\r\n"
"Host: %s\r\n"
"Content-type: multipart/form-data\r\n"
"Content-length: %d\r\n\r\n"
"Content-Disposition: %s; filename: %s\n"
I am sending the above string from a cpp program in client to the server, running Apache, which handles the data through a cgi script, also written in cpp. The data is placed with the Content Disposition attribute. Can anybody please point it out to me as to how would I transform the above to a HTTP PUT?

Related

Receiving http requests with winsock

For educational purposes I am trying to make a web api in c++. the web api needs to be able to listen for http requests(GET, POST etc.), when it receives a http request it needs to be able to send data back to the client. Because it is for educational purposes I would like to do it without unnecessary libraries. Now the first thing I need to do is make the api able to receive requests and respond on that, after some research on google I found out that winsock is probably the most basic way to setup sockets for windows but I could find very little on receiving http requests.
My question is: Is it possible with winsock to receive a http request from the browser, and send data back to the browser?.
My question is: Is it possible with winsock to receive a http request from the browser, and send data back to the browser?
Yes. ^^
It is, Because HTTP is a protocol that (usually) uses TCP as the underlying transportation protocol.
But trying to build a real HTTP layer on top of a simple win32 socket is a bit too much even for an experienced C++ developer.
Many un-experienced C++ developers would probably dismiss this task as a "well, you just need to read some data, parse the headers, assemble your own HTTP response and send it back".
but..
You will have to support
TLS, with all the nasty private keys/public keys implementation
Redirection
Chunked Transfer
G-Zip transfer
and the list goes on and on..
So practically speaking, if you just want to to accept a socket, read some data and send some basic HTTP response than yes. If you want a reliable, professional HTTP library - probably no.
You can check this page https://github.com/ReneNyffenegger/cpp-webserver to see simple winsock server implementation for HTTP. Web server implementation is not so difficult. Of course you should have time for it.

HTTP request does not work

I'm programming some kind of browser in c++ using winsock and got struck in some kind of error. The program works just fine for some pages in the internet, but for some reason it doesn't work for all of them.
https://imageshack.com/a/v56q/1
As seen in these images the composed version of Fiddler works while my own program fails.
I thought that maybe the HTTPS connection might be the problem, but it doesn't even seem to need a handshake or something similar. The sending part of the program is certainly not the problem because it works with other pages (e.g. the ones in the comments).
Thanks in advance!
I thought that maybe the HTTPS connection might be the problem, but it doesn't even seem to need a handshake or something similar.
Yes, HTTPS requires that you perform a rather complicated handshake, which is why essentially nobody attempts to implement HTTPS directly on sockets, and instead uses WinHTTP or WinINET, the two HTTP stacks included in Windows.
While Fiddler is running, you can kinda "cheat" by sending your plaintext request (containing a HTTPS url) to Fiddler, which will then perform the proper secure handshake with the remote server on your behalf and then return the response to your client. (Fiddler is acting as a HTTP-to-HTTPS gateway in this scenario.

HTTP connection through DMZ / proxy in C++

I want to connect from webserver via dedicated proxy to the intranet. I am not sure if it matters I want to send and receive XML. It would be great if I could use HTTP.
I know of one open port 78xx which I successfully used with a TCP socket as described in this excellent tutorial
Is it possible? Or does the answer depend on the actual proxy configuration - if it scans for the protocol, and dislikes it it's gonna be blocked!?
And what library would you recommend? I just found pion - Can i link it statically? It's almost not possible to install sth on the web server for me.
EDIT My question is probably two-fold:
First, I have to add, there is an existing communication client+server, but the server is a mixup of the concrete socket and networking implementation and the API to the database, consisting of about 10 commands I find hard to extend. So I ask for a generic lib so I can rewrite that API from scratch.
Second, I need session handling, the webapplication passes the user login data to that client and there is a session-id returned which is used for all further communication - until it expires. That was the reason I asked for HTTP, but meanwhile i realized http itself is stateless.
The answer is.... in progress.- I need to practice more with c++ tcp libs etc.
My post was unfortunately hard too understand, Had some confusion about that all.

SOAP request over HTTP delay

I am trying to send a SOAP request over HTTP for a web service through the following channels:
Telnet (HP-UX)
C client that opens a socket, writes XML and reads reasponse(HP-UX)
Perl client that does the same thing as the C client above(HP-UX)
Through SOAP UI application (http://www.soapui.org/)(Windows Machine)
While SOAP UI gets a response in about 100ms seconds or so; the rest of the channels get the same response but very slow.
I am wondering what might be the problem. If anybody has any idea about this please let me know.
Possibly the connection stays open per default for subsequent requests (not uncommon for webservers which expect you to request all kinds of javascript files, images, css files directly afterwards). You might want to try to send the Connection: close header.
Check the protocol , may be you are using HTTP1.0 not HTTP1.1

Are there any CURL alternatives for C++?

I hate CURL it is too bulky with too many dependencies when all I need to do is quickly open a URL. I don't even need to retrieve the contents of the web page, I just need to make the GET HTTP request to the server.
What's the most minimal way I can do this and don't say CURL !##$
There are lots of choices! Try libwww -- but be warned, most people strongly prefer libcurl. It's much easier to use.
There's a very light way and I've done this myself when implementing a high-scale back end service for a large media provider in the UK.
This method is extremely operating-system specific.
open a TCP socket to the HTTP server
send a "GET /path/to/url HTTP/1.1\r\nHost: www.host.com\r\n\r\n" (the Host header is required for HTTP/1.1 and most virtual servers, don't forget the two blank lines, and a newline requires a carriage return as well for HTTP headers)
wait for the response
close the socket
If you are going to close the socket at the end of the connection you may also want to send a Connection: close\r\n as part of your headers to inform the web server that you will terminate the connection after retrieving the web page.
You may run into trouble if you're fetching an encoded or generated web page in which case you'll have to add logic to interpret the fetched data.
On Windows (Windows XP, Windows 2000 Professional with SP3 and above) you could use WinHttpReadData API. There's also an example at the bottom of that page.
More info on Windows HTTP Services on MSDN
I have used Winsock when I need as few dependencies as possible and it has worked well. You need to write more code than using a separate library or the Microsoft WinHTTP library.
The functions you need are WSAStartup, socket, connect, send, recv, closesocket and WSACleanup.
See sample code for the send function.
system("wget -q -O file.htm http://url.com");