ESP8266: Send client.remoteIP() to client - webserver

`ESP8266 Web server will not send client.remoteIP() to client browser.
void loop() {
// Listenning for new clients
WiFiClient client = server.available();
if (client) {
Serial.println("New client");
// bolean to locate when the http request ends
boolean blank_line = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && blank_line) {
getWeather();
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
// your actual web page that displays temperature
client.println("<!DOCTYPE HTML>");
client.println("<html>");
//client.println("<head><META HTTP-EQUIV=\"refresh\" CONTENT=\"15\"></head>");
client.println("<body><h1>ESP8266 Weather Web Server</h1>");
client.println("<table border=\"2\" width=\"456\" cellpadding=\"10\"><tbody><tr><td>");
client.println();
client.println(client.remoteIP());
client.println();
client.println("<h3>Temperature = ");
client.println(temperatureFString);
client.println("°F</h3><h3>Humidity = ");
client.println(humidityString);
client.println("%</h3><h3>Approx. Dew Point = ");
client.println(dpString);
client.println("°F</h3><h3>Pressure = ");
client.println(pressureString);
client.println("hPa (");
client.println(pressureInchString);
client.println("Inch)</h3></td></tr></tbody></table></body></html>");
int x;
for(x = 1;x < 2; x++)
{
Serial.println(client.remoteIP());
}
break;
}
if (c == '\n') {
// when starts reading a new line
blank_line = true;
}
else if (c != '\r') {
// when finds a character on the current line
blank_line = false;
}
}
}
// closing the client connection
delay(1);
client.stop();
Serial.println("Client disconnected.");
}
Is there a way that the client's IP can be displayed in the table of browser?
I have no problem doing a Serial.print(client.remoteIP()).

IPAddress is a class and does not return a String. Better to use in that fashion for your case :
client.remoteIP().toString().c_str()

Related

How to host a html using sd card

i wanna host a webserver from a sd card using ESP8266. i look through the github library SDWebServer, and i tried the code it came out following error
error: 'class String' has no member named 'clear' and the line of code "path.clear();" is causing this error
Can anyone help to solve or anyone has better example code to share with me?
/* SDWebServer - Example WebServer with SD Card backend for esp8266
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the ESP8266WebServer library for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Have a FAT Formatted SD Card connected to the SPI port of the ESP8266
The web root is the SD Card root folder
File extensions with more than 3 charecters are not supported by the SD Library
File Names longer than 8 charecters will be truncated by the SD library, so keep filenames shorter
index.htm is the default index (works on subfolders as well)
upload the contents of SdRoot to the root of the SDcard and access the editor by going to http://esp8266sd.local/edit
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <SPI.h>
#include <SD.h>
#define DBG_OUTPUT_PORT Serial
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "esp8266sd";
ESP8266WebServer server(80);
static bool hasSD = false;
File uploadFile;
void returnOK() {
server.send(200, "text/plain", "");
}
void returnFail(String msg) {
server.send(500, "text/plain", msg + "\r\n");
}
bool loadFromSdCard(String path) {
String dataType = "text/plain";
if (path.endsWith("/")) {
path += "index.htm";
}
if (path.endsWith(".src")) {
path = path.substring(0, path.lastIndexOf("."));
} else if (path.endsWith(".htm")) {
dataType = "text/html";
} else if (path.endsWith(".css")) {
dataType = "text/css";
} else if (path.endsWith(".js")) {
dataType = "application/javascript";
} else if (path.endsWith(".png")) {
dataType = "image/png";
} else if (path.endsWith(".gif")) {
dataType = "image/gif";
} else if (path.endsWith(".jpg")) {
dataType = "image/jpeg";
} else if (path.endsWith(".ico")) {
dataType = "image/x-icon";
} else if (path.endsWith(".xml")) {
dataType = "text/xml";
} else if (path.endsWith(".pdf")) {
dataType = "application/pdf";
} else if (path.endsWith(".zip")) {
dataType = "application/zip";
}
File dataFile = SD.open(path.c_str());
if (dataFile.isDirectory()) {
path += "/index.htm";
dataType = "text/html";
dataFile = SD.open(path.c_str());
}
if (!dataFile) {
return false;
}
if (server.hasArg("download")) {
dataType = "application/octet-stream";
}
if (server.streamFile(dataFile, dataType) != dataFile.size()) {
DBG_OUTPUT_PORT.println("Sent less data than expected!");
}
dataFile.close();
return true;
}
void handleFileUpload() {
if (server.uri() != "/edit") {
return;
}
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
if (SD.exists((char *)upload.filename.c_str())) {
SD.remove((char *)upload.filename.c_str());
}
uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
DBG_OUTPUT_PORT.print("Upload: START, filename: "); DBG_OUTPUT_PORT.println(upload.filename);
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (uploadFile) {
uploadFile.write(upload.buf, upload.currentSize);
}
DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: "); DBG_OUTPUT_PORT.println(upload.currentSize);
} else if (upload.status == UPLOAD_FILE_END) {
if (uploadFile) {
uploadFile.close();
}
DBG_OUTPUT_PORT.print("Upload: END, Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
}
}
void deleteRecursive(String path) {
File file = SD.open((char *)path.c_str());
if (!file.isDirectory()) {
file.close();
SD.remove((char *)path.c_str());
return;
}
file.rewindDirectory();
while (true) {
File entry = file.openNextFile();
if (!entry) {
break;
}
String entryPath = path + "/" + entry.name();
if (entry.isDirectory()) {
entry.close();
deleteRecursive(entryPath);
} else {
entry.close();
SD.remove((char *)entryPath.c_str());
}
yield();
}
SD.rmdir((char *)path.c_str());
file.close();
}
void handleDelete() {
if (server.args() == 0) {
return returnFail("BAD ARGS");
}
String path = server.arg(0);
if (path == "/" || !SD.exists((char *)path.c_str())) {
returnFail("BAD PATH");
return;
}
deleteRecursive(path);
returnOK();
}
void handleCreate() {
if (server.args() == 0) {
return returnFail("BAD ARGS");
}
String path = server.arg(0);
if (path == "/" || SD.exists((char *)path.c_str())) {
returnFail("BAD PATH");
return;
}
if (path.indexOf('.') > 0) {
File file = SD.open((char *)path.c_str(), FILE_WRITE);
if (file) {
file.write((const char *)0);
file.close();
}
} else {
SD.mkdir((char *)path.c_str());
}
returnOK();
}
void printDirectory() {
if (!server.hasArg("dir")) {
return returnFail("BAD ARGS");
}
String path = server.arg("dir");
if (path != "/" && !SD.exists((char *)path.c_str())) {
return returnFail("BAD PATH");
}
File dir = SD.open((char *)path.c_str());
path.clear();
if (!dir.isDirectory()) {
dir.close();
return returnFail("NOT DIR");
}
dir.rewindDirectory();
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
server.send(200, "text/json", "");
WiFiClient client = server.client();
server.sendContent("[");
for (int cnt = 0; true; ++cnt) {
File entry = dir.openNextFile();
if (!entry) {
break;
}
String output;
if (cnt > 0) {
output = ',';
}
output += "{\"type\":\"";
output += (entry.isDirectory()) ? "dir" : "file";
output += "\",\"name\":\"";
output += entry.name();
output += "\"";
output += "}";
server.sendContent(output);
entry.close();
}
server.sendContent("]");
server.sendContent(""); // Terminate the HTTP chunked transmission with a 0-length chunk
dir.close();
}
void handleNotFound() {
if (hasSD && loadFromSdCard(server.uri())) {
return;
}
String message = "SDCARD Not Detected\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
DBG_OUTPUT_PORT.print(message);
}
void setup(void) {
DBG_OUTPUT_PORT.begin(115200);
DBG_OUTPUT_PORT.setDebugOutput(true);
DBG_OUTPUT_PORT.print("\n");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
DBG_OUTPUT_PORT.print("Connecting to ");
DBG_OUTPUT_PORT.println(ssid);
// Wait for connection
uint8_t i = 0;
while (WiFi.status() != WL_CONNECTED && i++ < 20) {//wait 10 seconds
delay(500);
}
if (i == 21) {
DBG_OUTPUT_PORT.print("Could not connect to");
DBG_OUTPUT_PORT.println(ssid);
while (1) {
delay(500);
}
}
DBG_OUTPUT_PORT.print("Connected! IP address: ");
DBG_OUTPUT_PORT.println(WiFi.localIP());
if (MDNS.begin(host)) {
MDNS.addService("http", "tcp", 80);
DBG_OUTPUT_PORT.println("MDNS responder started");
DBG_OUTPUT_PORT.print("You can now connect to http://");
DBG_OUTPUT_PORT.print(host);
DBG_OUTPUT_PORT.println(".local");
}
server.on("/list", HTTP_GET, printDirectory);
server.on("/edit", HTTP_DELETE, handleDelete);
server.on("/edit", HTTP_PUT, handleCreate);
server.on("/edit", HTTP_POST, []() {
returnOK();
}, handleFileUpload);
server.onNotFound(handleNotFound);
server.begin();
DBG_OUTPUT_PORT.println("HTTP server started");
if (SD.begin(SS)) {
DBG_OUTPUT_PORT.println("SD Card initialized.");
hasSD = true;
}
}
void loop(void) {
server.handleClient();
MDNS.update();
}
The code compiles without warnings and errors. Used environment:
Arduino IDE v 1.8.13
ESP8266 community edition v 2.6.3
windows machine
My guess is old ESP or Arduino libs - versions above.
The code is ok as a starter for own projects.
One starting tip:
Replace all Strings with char functionsor you will have stability problems later on (Heap fragmentation)
you have to remove "hasSD &&" from void handleNotFound function.
it worked for me.

Windows Service is working fine with character set as unicode but same code with multi-byte is start to failed with 1053 error

The basic windows service example code in c++ with release configuration + unicode character set is perfectly start using sc start cmd in admin console but when i change the configuration release+ multi-byte than sc start cmd fail with most common service error : 1053 -The service did not respond to the start or control request in a timely fashion.
I don't know what is the relation between this unicode vs multi-byte config. even i have cross-check each function suffix and that is expected like in unicode mode suffix is W and in multi-byte mode suffix is A
#define SERVICE_NAME "USB Device Monitor Service"
#define SLEEP_TIME (1000)
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[1];
ServiceTable[0].lpServiceName = SERVICE_NAME;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
StartServiceCtrlDispatcher(ServiceTable);
}
void ServiceMain()
{
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
Status.dwCurrentState = SERVICE_START_PENDING;
Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
Status.dwWin32ExitCode = 0;
Status.dwServiceSpecificExitCode = 0;
Status.dwCheckPoint = 0;
Status.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandlerEx(SERVICE_NAME, (LPHANDLER_FUNCTION_EX)ControlHandler, 0);
if ((SERVICE_STATUS_HANDLE)0 == hStatus)
{
// Error
}
SetServiceStatus(hStatus, &Status);
Status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &Status);
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
// Initialization
hDeviceNotify = RegisterDeviceNotification((HANDLE)hStatus, &NotificationFilter, DEVICE_NOTIFY_SERVICE_HANDLE);
if (NULL == hDeviceNotify)
{
// Error
}
while (SERVICE_RUNNING == Status.dwCurrentState)
{
Sleep(SLEEP_TIME);
}
}
DWORD ControlHandler(DWORD dwControl, DWORD dwEventType,
LPVOID lParam, LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
UnregisterDeviceNotification(hDeviceNotify);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
CloseHandle(hPipe);
return NO_ERROR;
case SERVICE_CONTROL_DEVICEEVENT:
if ((DBT_DEVICEARRIVAL == dwEventType) || (DBT_DEVICEREMOVECOMPLETE == dwEventType))
{
try
{
DEV_BROADCAST_HDR* header = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam);
if (DBT_DEVTYP_DEVICEINTERFACE == header->dbch_devicetype)
{
//parse intrested USB device only
}
}
catch (const std::nullptr_t /*ex*/)
{
//"ERROR: Processing WM_DEVICECHANGE failed
}
}
break;
default:
//"ERROR : Unknown dwControl: dwControl)
SetServiceStatus(hStatus, &Status);
break;
}
return NO_ERROR;
}
Your ServiceMain() and ControlHandler() functions are declared wrong, but you are using type-casts to stop the compiler from complaining. Any time you have to resort to using a type-cast to quiet the compiler, think about what your code is trying to do, as it is likely doing something wrong.
Also, the SERVICE_TABLE_ENTRY[] array that you are passing to StartServiceCtrlDispatcher() is incomplete - you are not NULL-terminating the array, like the documentation says to do.
For that matter, you claim that your service works when compiling for Unicode, but the code you have shown won't actually compile under Unicode, because the ServiceTable[0].lpServiceName field will be expecting a Unicode string but the code shown is assigning an ANSI string instead, which is an error.
I suggest you read Microsoft's documentation, and pay close attention to the examples it gives:
Service Program Tasks
The following tasks are performed by service programs:
Writing a Service Program's main Function
Writing a ServiceMain Function
Writing a Control Handler Function
Related Topics
The Complete Service Sample
With that said, try something more like this:
#define SERVICE_NAME TEXT("USB Device Monitor Service")
HANDLE hStopEvent = NULL;
SERVICE_STATUS_HANDLE hStatus = NULL;
SERVICE_STATUS Status;
DWORD WINAPI ControlHandler(DWORD dwControl, DWORD dwEventType,
LPVOID lParam, LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_INTERROGATE:
return NO_ERROR;
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
SetEvent(hStopEvent);
return NO_ERROR;
case SERVICE_CONTROL_DEVICEEVENT:
if ((DBT_DEVICEARRIVAL == dwEventType) || (DBT_DEVICEREMOVECOMPLETE == dwEventType))
{
try
{
DEV_BROADCAST_HDR* header = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam);
if (DBT_DEVTYP_DEVICEINTERFACE == header->dbch_devicetype)
{
//parse intrested USB device only
}
}
catch (const std::nullptr_t /*ex*/)
{
//"ERROR: Processing WM_DEVICECHANGE failed
}
}
break;
default:
//"ERROR : Unknown dwControl: dwControl)
break;
}
return NO_ERROR;
}
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
hStatus = RegisterServiceCtrlHandlerEx(SERVICE_NAME, &ControlHandler, 0);
if (!hStatus)
{
// Error
return;
}
ZeroMemory(&Status, sizeof(Status));
Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
Status.dwCurrentState = SERVICE_START_PENDING;
SetServiceStatus(hStatus, &Status);
// Initialization
hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hStopEvent)
{
// Error
Status.dwCurrentState = SERVICE_STOPPED;
Status.dwWin32ExitCode = GetLastError();
SetServiceStatus(hStatus, &Status);
return;
}
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
HDEVNOTIFY hDeviceNotify = RegisterDeviceNotification((HANDLE)hStatus, &NotificationFilter, DEVICE_NOTIFY_SERVICE_HANDLE);
if (!hDeviceNotify)
{
// Error
Status.dwCurrentState = SERVICE_STOPPED;
Status.dwWin32ExitCode = GetLastError();
SetServiceStatus(hStatus, &Status);
return;
}
Status.dwCurrentState = SERVICE_RUNNING;
Status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus(hStatus, &Status);
WaitForSingleObject(hStopEvent, INFINITE);
Status.dwCurrentState = SERVICE_STOP_PENDING;
Status.dwControlsAccepted = 0;
SetServiceStatus(hStatus, &Status);
UnregisterDeviceNotification(hDeviceNotify);
CloseHandle(hStopEvent);
Status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &Status);
}
int main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = SERVICE_NAME;
ServiceTable[0].lpServiceProc = &ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}

How to solve ConnectionNotFoundException in JavaME

I'm trying to connect to the internet via my J2ME application on my Netbeans emulator with the following function which connects to a webpage and prints out its HTML using System.out.println().
function getHTML(String url)
{
HttpConnection httpConn = null;
InputStream is = null;
OutputStream os = null;
try
{
httpConn = (HttpConnection)Connector.open(url);
int respCode = httpConn.getResponseCode();
if (respCode == httpConn.HTTP_OK)
{
StringBuffer sb = new StringBuffer();
os = httpConn.openOutputStream();
is = httpConn.openDataInputStream();
int chr;
while ((chr = is.read()) != -1)
sb.append((char) chr);
System.out.println(sb.toString());
os.close();
is.close();
}
else
{
System.out.println("Error " + respCode);
}
httpConn.close();
}
catch(IOException ioex)
{
ioex.printStackTrace();
}
}
But I've been getting the following error;
javax.microedition.io.ConnectionNotFoundException: error 10051 in socket::open
at com.sun.midp.io.j2me.socket.Protocol.open0(), bci=0
at com.sun.midp.io.j2me.socket.Protocol.connect(), bci=209
at com.sun.midp.io.j2me.socket.Protocol.open(), bci=216
at com.sun.midp.io.j2me.socket.Protocol.openPrim(), bci=4
at com.sun.midp.io.j2me.http.Protocol.createConnection(), bci=41
at com.sun.midp.io.j2me.http.Protocol.connect(), bci=41
at com.sun.midp.io.j2me.http.Protocol.streamConnect(), bci=164
at com.sun.midp.io.j2me.http.Protocol.startRequest(), bci=7
at com.sun.midp.io.j2me.http.Protocol.sendRequest(), bci=33
at com.sun.midp.io.j2me.http.Protocol.sendRequest(), bci=3
at com.sun.midp.io.j2me.http.Protocol.getResponseCode(), bci=5
I know my code isn't the problem because this used to work on my old laptop, but it hasn't worked since I installed Netbeans on my new laptop. Is it because of my internet connection, or my firewall settings, or my settings in Netbeans, or did I just not install Netbeans properly?
If you want to send some data and receive means then try the coding
try
{
httpConn = (HttpConnection)Connector.open(url);
os = httpConn.openOutputStream();
//Writing data to os
os.write(b); //Here b is a byte array
os.flush();
int respCode = httpConn.getResponseCode();
if (respCode == httpConn.HTTP_OK)
{
StringBuffer sb = new StringBuffer();
is = httpConn.openDataInputStream();
int chr;
while ((chr = is.read()) != -1)
sb.append((char) chr);
System.out.println(sb.toString());
}
else
{
System.out.println("Error " + respCode);
}
}
catch(IOException ioex)
{
ioex.printStackTrace();
}
if(os!=null) os.close();
if(is!=null) is.close();
if(httpConn!=null) httpConn.close();
os=null;is=null;httpConn=null;
}

tool chain allowing two-way communication between a D app and a browser

I wish to have an app written in the D programming language update its display in a browser. The browser should also send input data back to the app.
I'm still quite new to programming and am confused with how sockets/websockets/servers all fit together. Can anyone suggest an approach?
Many thanks to gmfawcett for the link to his basic D server example which I've mated with a bare-bones websocket implementation of the version 8 spec that I found elsewhere (currently only works in Chrome 14/15, I believe). It's pretty much cut'n'paste but seems to work well enough and I expect it will be sufficient in serving my needs.
If anyone has the inclination to cast a quick eye over my code for any glaring no-nos, please feel free to do so - and thanks!
Bare-bones websocket impl: http://blog.vunie.com/implementing-websocket-draft-10
Websocket v8 spec (protocol-17): https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-17
module wsserver;
import std.algorithm;
import std.base64;
import std.conv;
import std.stdio;
import std.socket;
import std.string;
//std.crypto: https://github.com/pszturmaj/phobos/tree/master/std/crypto
import crypto.hash.base;
import crypto.hash.sha;
struct WsServer
{
private
{
Socket s;
Socket conn;
string subProtocol;
}
this(string host, ushort port = 8080, string subProtocol = "null")
{
this.subProtocol = subProtocol;
s = new TcpSocket(AddressFamily.INET);
s.bind(new InternetAddress(host, port));
s.listen(8);
conn = s.accept();
writeln("point/refresh your browser to \"http://", host, "\" to intiate the websocket handshake");
try
{
initHandshake(conn);
}
catch (Throwable e)
{
stderr.writeln("thrown: ", e);
}
}
~this()
{
conn.shutdown(SocketShutdown.BOTH);
conn.close();
s.shutdown(SocketShutdown.BOTH);
s.close();
}
string data()
{
ubyte[8192] msgBuf;
auto msgBufLen = conn.receive(msgBuf);
auto firstByte = msgBuf[0];
auto secondByte = msgBuf[1];
// not sure these two checks are woking correctly!!!
enforce((firstByte & 0x81), "Fragments not supported"); // enforce FIN bit is present
enforce((secondByte & 0x80), "Masking bit not present"); // enforce masking bit is present
auto msgLen = secondByte & 0x7f;
ubyte[] mask, msg;
if(msgLen < 126)
{
mask = msgBuf[2..6];
msg = msgBuf[6..msgBufLen];
}
else if (msgLen == 126)
{
mask = msgBuf[4..8];
msg = msgBuf[8..msgBufLen];
}
foreach (i, ref e; msg)
e = msg[i] ^ mask[i%4];
debug writeln("Client: " ~ cast(string) msg);
return cast(string) msg;
}
void data(string msg)
{
ubyte[] newFrame;
if (msg.length > 125)
newFrame = new ubyte[4];
else
newFrame = new ubyte[2];
newFrame[0] = 0x81;
if (msg.length > 125)
{
newFrame[1] = 126;
newFrame[2] = cast(ubyte) msg.length >> 8;
newFrame[3] = msg.length & 0xFF;
}
else
newFrame[1] = cast(ubyte) msg.length;
conn.send(newFrame ~= msg);
debug writeln("Server: " ~ msg);
}
private void initHandshake(Socket conn)
{
ubyte[8192] buf; // big enough for some purposes...
size_t position, headerEnd, len, newpos;
// Receive the whole header before parsing it.
while (true)
{
len = conn.receive(buf[position..$]);
debug writeln(cast(string)buf);
if (len == 0) // empty request
return;
newpos = position + len;
headerEnd = countUntil(buf[position..newpos], "\r\n\r\n");
position = newpos;
if (headerEnd >= 0)
break;
}
// Now parse the header.
auto lines = splitter(buf[0..headerEnd], "\r\n");
string request_line = cast(string) lines.front;
lines.popFront;
// a very simple Header structure.
struct Pair
{
string key, value;
this(ubyte[] line)
{
auto tmp = countUntil(line, ": ");
key = cast(string) line[0..tmp]; // maybe down-case these?
value = cast(string) line[tmp+2..$];
}
}
Pair[] headers;
foreach(line; lines)
headers ~= Pair(line);
auto tmp = splitter(request_line, ' ');
string method = tmp.front; tmp.popFront;
string url = tmp.front; tmp.popFront;
string protocol = tmp.front; tmp.popFront;
enum GUID_v8 = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // version 8 spec... might change
auto sha1 = new SHA1;
sha1.put(strip(headers[5].value) ~ GUID_v8);
auto respKey = to!string(Base64.encode(sha1.finish()));
// Prepare a response, and send it
string resp = join(["HTTP/1.1 101 Switching Protocols",
"Upgrade: websocket",
"Connection: Upgrade",
"Sec-WebSocket-Accept: " ~ respKey,
"Sec-WebSocket-Protocol: " ~ subProtocol,
""],
"\r\n");
conn.send(cast(ubyte[]) (resp ~ "\r\n"));
debug writeln(resp);
}
}

apache HttpClient to access facebook

Any examples, tips, guidance for the following scenario?
I have used Apache HttpClient to simulate the functionality of browser to access facebook through java application. to do that first i have to provide user credentials. i have used examples provided in the following web site.
http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/examples/
But non of these methods works for facebook, following is the test code i have written for this purpose. i have not provided the all the methods written, only the method used to login to the facebook account is given here. relay appreciate any help
private static int connectAndLogin(String email, String pass){
logger.trace("Facebook: =========connectAndLogin begin===========");
String httpResponseBody = getMethod("http://www.facebook.com/login.php");
if(httpResponseBody == null){
//Why don't we try again?
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
logger.trace(e.getMessage());
}
httpResponseBody = getMethod("http://www.facebook.com/login.php");
}
logger.trace("Facebook: ========= get login page ResponseBody begin===========");
logger.trace(httpResponseBody);
logger.trace("Facebook: +++++++++ get login page ResponseBody end+++++++++");
logger.trace("Facebook: Initial cookies: ");
List<Cookie> cookies = getCookies();
if (cookies.isEmpty()) {
logger.trace("Facebook: None");
} else {
for (int i = 0; i < cookies.size(); i++) {
logger.trace("Facebook: - " + cookies.get(i).toString());
}
}
if(httpResponseBody == null){
logger.warn("Facebook: Warning: Failed to get facebook login page.");
}
try
{
HttpPost httpost = new HttpPost("http://www.facebook.com/login.php");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("email", email));
nvps.add(new BasicNameValuePair("pass", pass));
//don't know if is this necessary
nvps.add(new BasicNameValuePair("login", ""));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
logger.info("Facebook: #executing post method to:" + "http://www.facebook.com/login.php");
HttpResponse loginPostResponse = getHttpClient().execute(httpost);
HttpEntity entity = loginPostResponse.getEntity();
logger.trace("Facebook: Login form post: " + loginPostResponse.getStatusLine());
if (entity != null) {
logger.trace("Facebook: "+EntityUtils.toString(entity));
entity.consumeContent();
} else {
logger.error("Facebook: Error: login post's response entity is null");
return FacebookErrorCode.kError_Login_GenericError;
}
logger.trace("Facebook: Post logon cookies:");
cookies = getCookies();
if (cookies.isEmpty()) {
logger.trace("Facebook: None");
} else {
for (int i = 0; i < cookies.size(); i++) {
logger.trace("Facebook: - " + cookies.get(i).toString());
}
}
int statusCode = loginPostResponse.getStatusLine().getStatusCode();
logger.info("Facebook: Post Method done(" + statusCode + ")");
switch(statusCode){
case 100: break;//we should try again;
case 301:
case 302:
case 303:
case 307:
{
//redirect
// Header[] headers = loginPostResponse.getAllHeaders();
// for (int i=0; i<headers.length; i++) {
// logger.trace("Facebook: "+headers[i]);
// }
// Header locationHeader = loginPostResponse.getFirstHeader("location");
// if(locationHeader != null){
// homePageUrl = locationHeader.getValue();
// logger.info("Facebook: Redirect Location: " + homePageUrl);
// if(homePageUrl == null
// || !homePageUrl.contains("facebook.com/home.php")){
// logger.error("Facebook: Login error! Redirect Location Url not contains \"facebook.com/home.php\"");
// return FacebookErrorCode.kError_Login_GenericError;
// }
// } else {
// logger.warn("Facebook: Warning: Got no redirect location.");
// }
}
break;
default:;
}
}
catch (IOException ioe)
{
logger.error("Facebook: IOException\n" + ioe.getMessage());
return FacebookErrorCode.kError_Global_ValidationError;
}
logger.trace("Facebook: =========connectAndLogin end==========");
return FacebookErrorCode.Error_Global_NoError;
}
The following code, based on that sample, worked for me:
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.facebook.com/login.php");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
entity.consumeContent();
}
System.out.println("Initial set of cookies:");
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
HttpPost httpost = new HttpPost("http://www.facebook.com/login.php");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("email", "******"));
nvps.add(new BasicNameValuePair("pass", "*******"));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpclient.execute(httpost);
entity = response.getEntity();
System.out.println("Double check we've got right page " + EntityUtils.toString(entity));
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
entity.consumeContent();
}
System.out.println("Post logon cookies:");
cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
httpclient.getConnectionManager().shutdown();
I am not sure if your code was managing properly cookies (and session id kept within one of them), maybe that was the problem. Hope this will help you.
Just to make clear version issue: I was using HttpClient version 4.X, not the old one (3.X). They differ significantly.
Perhaps you should use a tool, such as Selenium
Have you taken a look at HtmlUnit. It wraps the HttpClient to create a headless Java browser, with javaScript execution. This way you are not trying to hack the individual forms all the time.