Correct http response to video stream - http

I'm currently developing my own little http server for video streaming, and i can't for the life of me figure out how this actually works...
This is the request i get from the client:
"GET / HTTP/1.1
Host: 127.0.0.1:8080
Accept: /
User-Agent: QuickTime.7.6.6 (qtver=7.6.6;cpu=IA32;os=Mac 10.6.4)
Connection: close
"
To which my http server responds(actual code):
response << "HTTP / 1.1 200 OK" << "\r\n"
<< "Accept-Ranges: bytes" << "\r\n"
<< "Connection: close" << "\r\n"
<< "Content-Type: video/x-msvideo" << "\r\n"
<< "\r\n";
followed by the actual video as a bytearray.
The video doesnt play... What am I doing wrong?

Two debugging suggestions:
Telnet directly to your webserver (e.g. telnet 127.0.0.1 8080) and type in the get request manually. Verify that the response you receive back are like you expect. This might cause your terminal settings/display in the window you run telnet to be messed up, but it is a very quick and simple test.
You can also capture the traffic with wireshark.

Related

HTTP REQUEST via ENC28J60 ethercard.h (Arduino Mega2560)

We would like to send a http request with ethercard.h.
But when we doing this
ether.browseUrl(PSTR("GET /"), "", website, my_callback);
We get a 400 bad request answer.
We would like to test http request like:
-POST
-HEAD
-PUT
-DELETE
-TRACE
-OPTIONS
But it seems only this is working:
ether.browseUrl(PSTR("/"), "", website, my_callback);
but why?
For GET request you don't need to make a special definition. All requests are GET in default. That's why your request works without any definition. So i can share with you a POST request example. You can proceed from here:
Stash::prepare(PSTR("POST http://$F/$F.csv HTTP/1.0" "\r\n"
"Host: $F" "\r\n"
"Content-Length: $D" "\r\n"
"Content-Type: application/x-www-form-urlencoded" "\r\n"
"\r\n"
"$H"),
website, PSTR(PATH), website, stash.size(), sd);
It even has a link to its explanation. POST Request Example

GET http request from Microcontroller to server (API)

I'm working with a stm32f4 microcontroller using lwip/stack, i use it to controle send http requests via ethernet .
the following code works fine:
sprintf(buffer, "GET /api/callAction?deviceID=80&name=turnOn\r\n");
strcat(buffer, "Host: 192.168.2.7\r\n");
strcat(buffer, "Connection: close\r\n");
strcat(buffer, "\r\n");
the problem is when the sever needs authentication like this :
admin:admin#192.168.2.7/api/callAction?deviceID=80&name=turnOn
i have tried adding an authorization part to the code :
strcat(buffer, "Host: admin:admin#192.168.2.7\r\n");
But the http request doesn't work .
Any ideas?
ps: im using Keil ARM /stm32f4 / lwip stack
Server: Fibaro home center lite
Have a read here:
https://en.wikipedia.org/wiki/Basic_access_authentication
you want to pass this string
Authorization: Basic XXXXXXXXXXXXXXXX
where XXXXXXXXXXXXXXXX is the Base64 version of username:password
for example, if username is Aladdin and password is OpenSesame then you have to Base64 encode the string Aladdin:OpenSesame which results into QWxhZGRpbjpPcGVuU2VzYW1l
you string is then:
Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
Just strcat it as you do for all the other stuff:
strcat(buffer, "Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l\r\n");

PUT http request query

Actually I am trying to send PUT request to a remote server the request is successfully send to the remote server but unfortunately the request is considered a bad request it can not see the body of the request I hope my discription is clear and here is the code for sending the request in Arduino programming language:
Serial.println("Sending to Server: ");
client.print("PUT /***/***/sensor/uod/1/A/1 HTTP/1.1\n");
Serial.print("PUT /***/***/sensor/uod/1/A/1 HTTP/1.1");
client.print("Host: ********.koding.io\n");
client.print("Cache-Control: no-cache\n");
client.print("Content-Type: application/x-www-form-urlencoded\r\n\r\n");
client.print("status=1");
one thing I want to mention that from the server side I used a tool that is called postman and from it it works successfully without any error and actually I have taken it's http request and convert it into the code to be send and you can find the http request below:
PUT /***/***/sensor/uod/1/A/1 HTTP/1.1
Host: *******.koding.io
Cache-Control: no-cache
Postman-Token: 8740ccb4-c0f2-a916-fd52-3089e4f3cbc9
Content-Type: application/x-www-form-urlencoded
status=0
I have solve the problem by adding content-Length: 10 header
Serial.println("Sending to Server: ");
client.print("PUT /***/***/sensor/uod/1/A/1 HTTP/1.1\n");
Serial.print("PUT /***/***/sensor/uod/1/A/1 HTTP/1.1");
client.print("Host: *********.koding.io\n");
client.print("Cache-Control: no-cache\n");
client.print("Content-Type: application/x-www-form-urlencoded\r\n");
client.print("Content-Length: 10\r\n\r\n");
client.print("status=1\r\n");

HTTP headers for chunked encoding POST - Error 411

I'm sending data to a server with an Arduino which requires constructing an HTML POST line-by-line. I don't necessarily know the Content-Length a-priori, so I am using "chunked" encoding.
When I tried this example post from Wikipedia with the "Transfer-Encoding" option as specified in rfc2616
client.println("POST /myurl HTTP/1.1");
client.println("Host: 12.345.679.999"); // replaced with the test server's IP
client.println("User-Agent: Arduino/1.0");
client.println("Transfer-Encoding: chunked");
client.println();
client.println("4");
client.println("test");
client.println("0");
client.println();
or, with escape characters explicit:
client.print("4\r\ntest\r\n0\r\n\r\n");
I receive the error from my server:
HTTP/1.1 411 Length Required
A request of the requested method POST requires a valid Content-length.
Server: Apache/2.2.22 (Ubuntu)
However, "chunked" encoding shouldn't require a Content-Length header field, see 4.4 - Message Length in rfc2616
Am I missing a field? Why doesn't this call work?
For the record, the non-Chunked-Encoding works:
if(client.connect(server, 80)){
String PostData = "test";
Serial.println("POST /myurl HTTP/1.1");
client.println("Host: 12.345.679.999"); // replaced with the test server's IP
Serial.println("User-Agent: Arduino/1.0");
Serial.print("Content-Length: ");
Serial.println(PostData.length());
Serial.println();
Serial.println(PostData);
}
UPDATE
From the apache2 error.log: "chunked Transfer-Encoding forbidden"
After finding
chunked Transfer-Encoding forbidden
in my Apache2 log I concluded that the error was not in the POST that I was making.
I found that modwsgi (the middle-layer between apache and django) does not enable chunked transfer-encoding by default. In the past, chunked wasn't supported at all
Refering to the change-log in the new version of modwsgi, I found that writing
WSGIChunkedRequest On
in my apache httpd.conf file allowed chunked requests (no more 411 error)

Is this a valid HTTP response?

I am writing a web server using C++, which responds the following for all requests:
static std::string rsp[] = {
"HTTP/1.1 200 OK\r\n",
"Server: WebServer\r\n",
"Content-Type: text/html\r\n",
"Content-Length: 3\r\n",
"Connection: close\r\n",
"\r\n",
"123"
};
the content "123" can be successfully shown in browser. But when I use apache-ab to do a test, ab always show errors like this:
ab -n 1 -c 1 http://127.0.0.1:1080/
apr_socket_recv: Connection reset by peer (104)
I thought that I'm closing the socket too quickly, so I commented the close() function. But ab just hold, ab seems to be waiting for a complete response.
If you can correctly render the response (123) in your browser, then it means that there is nothing wrong with your server, but with the request ab is sending to your server is not understood by your server.
ab's requests are not necessarily the same as a web browser's requests. And ab is not fully http 1.1 complainant, it's a http1.0 client.
"It (ab) does not implement HTTP/1.x fully; only accepts some 'expected'
forms of responses.
Source
Try this:
0. See the request being sent to your server: ab -n 5 -c 5 -v 10 http://127.0.0.1:8000/ using the verbosity argument. You should see something like this:
GET / HTTP/1.0
Host: 127.0.0.1:8000
User-Agent: ApacheBench/2.3
Accept: */*
Using firebug or something, get the requests being sent from your browser.
Now, match them, see what is the difference in the requests being sent. Use ab -H to send those custom headers to your web server from ab.

Resources