nginx proxy_pass and rewrite for seafile proxy - mod-rewrite

I'm running a seafile vm (private network) behind a Plesk vm (public).
Right now I'm using apache as proxy but was wondering how to get this setup running with nginx only.
This works:
RewriteEngine On
ProxyPass /seafhttp http://192.168.10.102:8082
ProxyPassReverse /seafhttp http://192.168.10.102:8082
RewriteRule ^/seafhttp - [QSA,L]
RewriteRule ^/(.*) http://192.168.10.102:8000/$1 [P]
ProxyPassReverse / http://192.168.10.102:8000/
This doesn't:
location /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://192.168.10.102:8082;
client_max_body_size 0;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
send_timeout 36000s;
}
location ~ / {
proxy_pass http://192.168.10.101:8065;
}
But this again does work:
RewriteEngine On
RewriteRule ^/(.*) http://192.168.10.102:8000/$1 [P]
ProxyPassReverse / http://192.168.10.102:8000/
+
location /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://192.168.10.102:8082;
client_max_body_size 0;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
send_timeout 36000s;
}
What am I missing here?
Thanks
Max

Fix below:
location ^~ /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://192.168.10.102:8082;
client_max_body_size 0;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
send_timeout 36000s;
}
location ~ / {
proxy_pass http://192.168.10.102:8000;
}

Related

Arduino How to POST a request to a HTTPS with ArduinoHttpClient

I'm pretty new on Arduino. I'm using ArduinoHttpClient and need to POST a request in secure way (https://).
I'm not able to define the https:// on the serverName passed to HttpClient(ethernetClient, serverName, webServerPort).
When I use serverName = url (ssl9083.websiteseguro.com or 179.188.19.74) with port 443 the board hangs and after sometime returns -3 on httpClient.responseStatusCode().
I'm using Arduino Uno R3 with Ethernet Shield W5100.
I'd appreciate any help. Below the code.
Thank you in advance.
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <ArduinoHttpClient.h>
//UDP Variables
#define UDP_PACKET_SIZE 80 //UDP size
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress localIp(192, 168, 1, 9);
unsigned int localPort = 8888; // local port to listen on
char packetBuffer[UDP_PACKET_SIZE]; // buffer to hold incoming packet,
EthernetUDP Udp; // An EthernetUDP instance to let us send and receive packets over UDP
//Http Variables
// Environment = P, H, D
char ENV[1] = {'H'};
const char* devServerName = "192.168.1.105";
const char* homServerName = "179.188.19.74";
//const char* homServerName = "https://ssl9083.websiteseguro.com/cfbinformatica"; Port 80 - NOK Frooze
//const char* homServerName = "https://ssl9083.websiteseguro.com"; Port 80 - NOK Frooze
//const char* homServerName = "ssl9083.websiteseguro.com/cfbinformatica"; Port 80 - NOK Frooze
//const char* homServerName = "ssl9083.websiteseguro.com"; Port 80 - OK conectou e retornou 404
//const char* homServerName = "179.188.19.74"; Port 80 OK conectou e retornou 404 - Port 443 retornou -3
const char* prdServerName = "ssl9083.websiteseguro.com/cfbinformatica";
String measurementServiceInsertMeasurement = "/MeasurementService.svc/InsertMeasurement";
String postInsertMeasurement = "/MeasurementService.svc/InsertMeasurement";
String serverName;
int webServerPort;
EthernetClient ethernetClient;
String authUserUid;
String userValidationUidCredentials;
void setup() {
setupSerial();
setupEthernetUDP();
setupHttp();
}
void setupSerial() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
}
void setupEthernetUDP() {
// start the Ethernet
Ethernet.begin(mac, localIp);
Serial.print("IP: ");
Serial.println(Ethernet.localIP());
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Etn shield notFnd");
while (1);
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Cable notConn");
while (1);
}
// start UDP
Udp.begin(localPort);
Serial.println("UDP init OK");
delay(5000);
}
void setupHttp() {
// Your Domain name with URL path or IP address with path
switch(ENV[0]) {
case 'P' :
serverName = prdServerName;
webServerPort = 443;
postInsertMeasurement = "/housemeterprd" + measurementServiceInsertMeasurement;
break;
case 'H' :
serverName = homServerName;
webServerPort = 443;
postInsertMeasurement = "/cfbinformatica/housemeterhom" + measurementServiceInsertMeasurement;
break;
default :
serverName = devServerName;
webServerPort = 80;
postInsertMeasurement = "/housemeterdev" + measurementServiceInsertMeasurement;
}
authUserUid = "Mg==";
userValidationUidCredentials = "PlUfGKwdXKmcF7HEoEPFu5QqGA3w52ukaUsIp5gOOlOXX928fermbxvGNsfbVr4Q";
Serial.println("HTTP init OK");
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i=0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
readPackage();
processPackage();
}
delay(10);
}
void readPackage() {
// read the packet into packetBufffer
Udp.read(packetBuffer, UDP_PACKET_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
}
void processPackage() {
switch(packetBuffer[0]) {
case 'A' :
handleAckMsg();
break;
case 'E' :
handleErrorMsg();
break;
default :
handleDataMsg();
}
}
void handleAckMsg() {
}
void handleErrorMsg() {
}
void handleDataMsg() {
String meterMAC;
meterMAC = convertToString(packetBuffer+35, 12);
String measurementValue;
measurementValue = convertToString(packetBuffer+20, 15);
String postData = "{\"meterMAC\":\"" + meterMAC + "\",\"measurementValue\":" + measurementValue +"}";
sendHttpPostDataMsg(&postData);
replyBack();
}
void sendHttpPostDataMsg(String *postData) {
Serial.print(serverName);
Serial.println(" Server ");
Serial.print(webServerPort);
Serial.println(" port ");
Serial.print(postInsertMeasurement);
Serial.println(" Url");
String data = *postData;
Serial.print(data);
Serial.println(" data ");
Serial.print(data.length());
Serial.println(" data length ");
HttpClient httpClient = HttpClient(ethernetClient, serverName, webServerPort);
httpClient.beginRequest();
httpClient.post(postInsertMeasurement);
httpClient.sendHeader("Content-Type", "application/json;charset=utf-8");
httpClient.sendHeader("Content-Length", data.length());
httpClient.sendHeader("Accept", "application/json");
httpClient.sendHeader("AuthUserUid", authUserUid);
httpClient.sendHeader("AuthUserValidationUid", userValidationUidCredentials);
httpClient.sendHeader("DeviceLanguage", "English");
httpClient.sendHeader("AuthUserProfile", "user");
httpClient.beginBody();
httpClient.print(data);
httpClient.endRequest();
int statusCode = httpClient.responseStatusCode();
String response = httpClient.responseBody();
httpClient.flush();
httpClient.stop();
Serial.print(statusCode);
Serial.println(" Http ret code");
Serial.print("Response: ");
Serial.println(response);
}
void replyBack() {
// send a reply to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(packetBuffer);
Udp.endPacket();
}
String convertToString(char* arr, int size)
{
int i;
String s = "";
for (i = 0; i < size; i++) {
s = s + arr[i];
}
return s;
}
here the results of the http call:
21:30:49.179 -> IP: 192.168.1.9
21:30:49.179 -> UDP init OK
21:30:54.226 -> HTTP init OK
21:31:05.891 -> Received packet of size 47
21:31:05.891 -> From 192.168.1.32, port 58412
21:31:05.937 -> Contents:
21:31:05.937 -> 000000000000000010330000000017.9090DEADBEEFFEED
21:31:05.985 -> 179.188.19.74 Server
21:31:06.031 -> 443 port
21:31:06.031 -> /cfbinformatica/housemeterhom/MeasurementService.svc/InsertMeasurement Url
21:31:06.125 -> {"meterMAC":"DEADBEEFFEED","measurementValue":0000000017.9090} data
21:31:06.172 -> 62 data length
21:32:07.214 -> -3 Http ret code
21:32:07.214 -> Response:

ESP8266 Returning code 400 on POST request in Django webapp

I deployed my django webapp to the internet but I can't POST request a data because it's returning
HTTP CODE 400,
const char* serverName = "https://example.com/api/v1/post_sample"; = returns 400 code.
but when I do: const char* serverName = "http://localhost:8000/api/v1/post_sample"; it works and return 201 code.
It didn't put any restrictions or auth for now on the web application. I even did a POST request on Postman to the web application I deployed, it also works.
Please help. Thanks!
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* serverName = "https://example.com/api/v1/post_sample";
unsigned long lastTime = 0;
unsigned long timerDelay = 5000;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(serverName);
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST("{\"value\":\"1\"}");
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}
You didn't establish a WiFiClient before trying to establish a http connection.
For POST request with ESP8266HTTPClient, you pass in the url when you establish http.begin(client, url) with an established client instance. See the example code. In your case, it should be:
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
HTTPClient http;
http.begin(client, serverName);
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST("{\"value\":\"1\"}");
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
If you url is an secure connection with https as you shown in your example url, then you will need to establish a secure client with a library like <WiFiClientSecureBearSSL.h>. See example.

Boost::asio async_connect fails to solve when using "localhost" instead of "127.0.0.1"

I am programming a tcp async client, but it fails to connect when I use "localhost" instead of "127.0.0.1". I mean, 127.0.0.1 works great but localhost fails miserabily. Please, any help fixing it or at least any explanation of what is going on? Maybe I am missusing the tcp::resolver and its results/iterators?
PD: Funny thing is that when using sync version to connect it works with both adresses (I mean using boost::asio::connect(socket, endpoints, error);)
#include <iomanip>
#include <iostream>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
class client
{
public:
client()
: io_context(),
acceptor(io_context),
socket(io_context)
{
}
void start(const char* host, const char* port)
{
tcp::resolver resolver(io_context);
tcp::resolver::results_type endpoints = resolver.resolve(host, port);//
socket.async_connect(endpoints->endpoint(), [=](boost::system::error_code error)
{
if (!error)
std::cout << "Connecting to " << host << ":" << port << "\n";
else
start(host, port);
});
}
void poll()
{
io_context.poll();
}
private:
boost::asio::io_context io_context;
tcp::acceptor acceptor;
tcp::socket socket;
};
int main(int argc, char* argv[])
{
if (argc != 1 && argc != 3)
{
std::cout << "async.exe <host> <port>" << std::endl;
return 0;
}
const char* host = (argc == 1 ? "localhost" : argv[1]);
const char* port = (argc == 1 ? "5031" : argv[2]);
try
{
std::cout << "Trying to connect to " << host << ":" << port << "...\n";
client c;
c.start(host, port);
while (true)
{
c.poll();
Sleep(100);
}
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
Thank you very much.
I have exactly this problem. The difference I found between when I used localhost and when I used an IP address (e.g. 127.0.0.1 or the IP address of the local machine) was that endpoints.size() was different. With an IP address endpoints.size() was 1 but with localhost endpoints.size() was 2. If I then drill down with a debugger I can see that one of these endpoints has an IP address of 127.0.0.1 and the other has an IP address of 0.0.0.0. What happens for me is that sometimes the endpoint list works OK, and sometimes it fails and I expect it is because only one of these endpoints actually provides a reliable route. It is easy enough to work around but strange behaviour otherwise. If I was guessing, I suspect that localhost provides both IP4 and IP6 endpoint whereas an IP4 address can only generate an IP4 endpoint. It still shouldn't fail though.

Finding out if an stored hostname in std::string is a ip address or a FQDN address in C++

Is it possible to find out a string is a FQDN or an IP address using boost lib in c++.
I have tried the below code which works fine for IP address but throws exception in case of FQDN.
// getHostname returns IP address or FQDN
std::string getHostname()
{
// some work and find address and return
return hostname;
}
bool ClassName::isAddressFqdn()
{
const std::string hostname = getHostname();
boost::asio::ip::address addr;
addr.from_string(hostname.c_str());
//addr.make_address(hostname.c_str()); // make_address does not work in my boost version
if ((addr.is_v6()) || (addr.is_v4()))
{
std::cout << ":: IP address : " << hostname << std::endl;
return false;
}
// If address is not an IPv4 or IPv6, then consider it is FQDN hostname
std::cout << ":: FQDN hostname: " << hostname << std::endl;
return true;
}
The fails in case of FQDN , as boost::asio::ip::address throws an exception in case of FQDN.
I have also tried searching for the same, in python something similar is availble but I need in c++.
Easy solution is that you just catch the exception thrown by addr.from_string
try
{
addr.from_string(hostname.c_str());
}
catch(std::exception& ex)
{
// not an IP address
return true;
}
Or if exceptions bother you, call the no-throw version of from_string:
boost::system::error_code ec;
addr.from_string(hostname.c_str(), ec);
if (ec)
{
// not an IP address
return true;
}
Otherwise, just use inet_pton which is available everywhere.
bool IsIpAddress(const char* address)
{
sockaddr_in addr4 = {};
sockaddr_in6 addr6 = {};
int result4 = inet_pton(AF_INET, address, (void*)(&addr4));
int result6 = inet_pton(AF_INET6, address, (void*)(&addr6));
return ((result4 == 1) || (result6 == 1));
}
bool isAddressFqdn(const char* address)
{
return !IsIpAddress(address);
}

Including mixins using variables for name in Sass

I'm trying to call a mixin using a variable as the name, like so:
#include $mixin-name;
That doesn't seem so difficult...
I've seen a few people online mention wanting to do this. This ticket (http://dev.vaadin.com/ticket/9546) says "fixed", which I assumed meant that in Sass 3.2 it was possible, but this comment from the Sass group on Google Groups seems to suggest otherwise: http://goo.gl/HtdHu
I see what they're saying, it seems many people who are asking about it could quite easily solve their issues another way.
I can't think of another way for my issue though, so let me explain and maybe someone might have an idea or two?
CSS Animation
I've created a mixin for #keyframes so that I can call #include animation(); and get the full list of prefixed and official #keyframes
#include keyframes(reveal) {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Gives me:
#-webkit-keyframes reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#-moz-keyframes reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#-ms-keyframes reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#-o-keyframes reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#keyframes reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Which is great! But if I use Compass transform in one of the keyframe states:
#include keyframes(round) {
from {
#include transform(rotateZ(-145deg));
opacity: 1;
}
to {
#include transform(rotateZ(-45deg));
opacity: 0.5;
}
}
then I end up getting something like:
#-webkit-keyframes round {
from {
-webkit-transform: rotateZ(-145deg);
-moz-transform: rotateZ(-145deg);
-ms-transform: rotateZ(-145deg);
-o-transform: rotateZ(-145deg);
transform: rotateZ(-145deg);
opacity: 1;
}
to {
-webkit-transform: rotateZ(-45deg);
-moz-transform: rotateZ(-45deg);
-ms-transform: rotateZ(-45deg);
-o-transform: rotateZ(-45deg);
transform: rotateZ(-45deg);
opacity: 0.5;
}
}
etc...
Prefixes inside prefixes
So, I know that this is pedantic, but it's really annoying me that I am declaring -webkit-animation, but then inside I have to declare all of the prefixes when what I want to do is only declare the same prefix as the keyframes and the official, eg:
#-webkit-keyframes round {
from {
-webkit-transform: rotateZ(-145deg);
transform: rotateZ(-145deg);
opacity: 1;
}
to {
-webkit-transform: rotateZ(-45deg);
transform: rotateZ(-45deg);
opacity: 0.5;
}
}
#-moz-keyframes round {
from {
-moz-transform: rotateZ(-145deg);
transform: rotateZ(-145deg);
opacity: 1;
}
to {
-moz-transform: rotateZ(-45deg);
transform: rotateZ(-45deg);
opacity: 0.5;
}
}
etc...
Mixin problems
So, I've created a mixin using #include experimental-value, but I can't automate it enough because
#function browser-is-prefix($browser, $prefix) {
#if $browser == $prefix {
#return true;
} #else {
#return false;
}
}
#mixin transform-prefix($transform, $browser) {
#include experimental-value(transform, $transform,
browser-is-prefix($browser, -moz),
browser-is-prefix($browser, -webkit),
browser-is-prefix($browser, -o),
browser-is-prefix($browser, -ms),
false, true);
}
#mixin animation-name($browser) {
from {
#include transform-prefix(transform(translate(-25px,200px) scale(0.5)), $browser);
opacity: 0;
}
to {
#include transform-prefix(transform(translate(0,0) scale(0.5)), $browser);
opacity: 1;
}
}
Calling #include animation-name(-webkit) will work great and give us:
#-webkit-keyframes animation-name {
from {
-webkit-transform: translate(-25px,200px) scale(0.5);
transform: translate(-25px,200px) scale(0.5);
opacity: 0;
}
to {
-webkit-transform: translate(0,0) scale(0.5);
transform: translate(0,0) scale(0.5);
opacity: 1;
}
}
But I can't automate it!
To automate the process I wanted to be able to call a mixin, something like #include prekeyframes(animation-name); and have prekeyframes do exactly what the keyframes mixin does above, except instead of blindly including the #content of the, it will include the mixin and only use the prefixes it should based on what prefix the #keyframes has:
#mixin prekeyframes($name) {
$prefixes : -webkit-, -moz-, -o-, -ms-, '';
#each $prefix in $prefixes {
#include $name($prefix);
}
}
This, of course, throws an error. If I interpolate $name (#include #{$name}($prefix)), it's still an issue.
So, I could just live with the extra transform values, or I could do it all manually, but I've always been really impressed with the flexibility of Sass and this seems really limiting to me...
To summarise:
I want to define the animation once, in one place.
I want to be able to #include transform within that animation.
I want the correctly prefixed transform inside the correctly prefixed #keyframes
I've spent a few hours on this now, and I'll continue to fiddle... But if anyone has similar experiences or problems, I'd love to know...
Thanks!
Check out Bourbon (relevant code and documentation), it's fantastic.

Resources