Curl ошибка 502

upstream prematurely closed connection

по результатам дискуссии выяснилось, что используется «upstream» в виде php-fpm, который в результате взаимодействия с libcurl «вылетает» при обращении к несуществующему доменному имени, что и приводит к выдаче программой nginx этого сообщения.

предлагаемый мною выход: проверять существование доменного имени до обращения к libcurl. например, с помощью функции checkdnsrr:

$ php -r 'if (checkdnsrr("ru.stackoverflow.com", $type="A")) { echo "dan";} else {echo "netn";}'
da
$ php -r 'if (checkdnsrr("rus.stackoverflow.com", $type="A")) { echo "dan";} else {echo "netn";}'
net

а извлекать доменное имя из url можно, например, с помощью функции parse_url:

$ php -r 'echo parse_url("http://rus.stackoverflow.com/blabla", $component=PHP_URL_HOST); echo "n";'
rus.stackoverflow.com

по поводу неработоспособности ipv6:

можно ограничить libcurl работой только с ipv4 (см. документацию):

curl_setopt ($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

From the browser the url is working. When I am trying with PHP curl — I am getting

502 - Bad Gateway error

Here is my code :

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url . $query_string);        
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
echo $data;

And the error —

<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.4.4</center>
</body>
</html>

Any suggestions?

I am using NGINX as a reverse proxy and just put up a new service written in Go.

The service has two endpoints

GET /tracking/ping

POST /tracking/customer

In NGINX, I am using the following to proxy the request

location /v1/location/ {
    proxy_pass http://path-to-tracking-service:8181/;
}

When curl the two endpoints such as the following, I get different results.

The GET /tracking/ping endpoint

curl -X GET https://example.com/v1/location/tracking/ping
"Pong!"

The ‘POST /tracking/customer` endpoint

curl -H "Content-Type: application/json" -d '{"userId":"1234"}'  https://example.com/v1/location/tracking/customer
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.9.12</center>
</body>

Not sure why this would happen. I am proxying other services I have and POST requests work perfectly fine.

Here is the nginx.conf

user nginx;
worker_processes 1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    proxy_connect_timeout       600;
proxy_send_timeout          600;
proxy_read_timeout          600;
send_timeout                600;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;

    #server {
        #include /etc/nginx/sites-enabled/*;
    #}

    server {
        listen 80;
        server_name *.example.com;
        #return 301 https://$host$request_uri;
        include /etc/nginx/sites-enabled/*;
    }

    server {


    #listen 80;
    listen 443 ssl;
    server_name *.example.com;

    ssl_certificate           /etc/ssl/example.crt;
    ssl_certificate_key       /etc/ssl/example.key;

    #ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    include /etc/nginx/sites-enabled/*;
    }
}

I have separate files that are being linked to /sites-enabled that include my proxy_params declarations.

Two of them are the following

location /v1/location/ {
    proxy_pass http://example.com:8181/;
}

location /v1/ {
    proxy_pass http://example.com:8282/;
}

I could see their maybe being an issue with it getting confused by the /v1 on both the proxies, but it works for the GET endpoint.

EDIT

Some people have brought up the point that it may be panicking so I checked the docker logs for the go container and got the following

location-tracking-staging-1 | 2016-03-14T02:35:33.580963673Z 2016/03/14 02:35:33 http: panic serving 10.7.1.5:35613: no reachable servers
location-tracking-staging-1 | 2016-03-14T02:35:33.581005488Z goroutine 97 [running]:
location-tracking-staging-1 | 2016-03-14T02:35:33.581012905Z net/http.(*conn).serve.func1(0xc820057b00)
location-tracking-staging-1 | 2016-03-14T02:35:33.581017348Z    /usr/local/go/src/net/http/server.go:1389 +0xc1
location-tracking-staging-1 | 2016-03-14T02:35:33.581030498Z panic(0x81e620, 0xc82013c5e0)
location-tracking-staging-1 | 2016-03-14T02:35:33.581034545Z    /usr/local/go/src/runtime/panic.go:426 +0x4e9
location-tracking-staging-1 | 2016-03-14T02:35:33.581038792Z main.RepoCreateVendorLocation(0xc82011ecb8, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
location-tracking-staging-1 | 2016-03-14T02:35:33.581042502Z    /go/src/location-tracking/repo.go:19 +0x178
location-tracking-staging-1 | 2016-03-14T02:35:33.581047145Z main.VendorLocationCreate(0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581050747Z    /go/src/location-tracking/handlers.go:63 +0x47b
location-tracking-staging-1 | 2016-03-14T02:35:33.581054911Z net/http.HandlerFunc.ServeHTTP(0x9965b0, 0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581058786Z    /usr/local/go/src/net/http/server.go:1618 +0x3a
location-tracking-staging-1 | 2016-03-14T02:35:33.581062770Z github.com/gorilla/mux.(*Router).ServeHTTP(0xc820010640, 0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581066604Z    /go/src/github.com/gorilla/mux/mux.go:103 +0x270
location-tracking-staging-1 | 2016-03-14T02:35:33.581070176Z net/http.serverHandler.ServeHTTP(0xc820056300, 0x7f8a4366d978, 0xc8200c2ea0, 0xc820119260)
location-tracking-staging-1 | 2016-03-14T02:35:33.581073992Z    /usr/local/go/src/net/http/server.go:2081 +0x19e
location-tracking-staging-1 | 2016-03-14T02:35:33.581077629Z net/http.(*conn).serve(0xc820057b00)
location-tracking-staging-1 | 2016-03-14T02:35:33.581081221Z    /usr/local/go/src/net/http/server.go:1472 +0xf2e
location-tracking-staging-1 | 2016-03-14T02:35:33.581084811Z created by net/http.(*Server).Serve
location-tracking-staging-1 | 2016-03-14T02:35:33.581088336Z    /usr/local/go/src/net/http/server.go:2137 +0x44e

  • Автор темы
  • #1

Доброго всем, подкажите как можно обойти защиту при парсинге через CURL
Либо cloudflare, либо самописный.

  • #2

Добавляете такую опцию curl_setopt( $ch, CURLOPT_HEADER, 1 ). В результате curl будет выдавать ответ с заголовками.

PHP:

$ch = curl_init();
curl_setopt( $ch, CURLOPT_HEADER, 1 );
$curlResult = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch );

if ($code == 502 || $code == 503){
echo 'Выпал код 502 или 503'
}

Из заголовков можно выпить ответ сервера.
Далее , если выпал нужный код ошибки, просто повторно делается запрос на получение страницы или таймаут и запрос.

Последнее редактирование: 15 Фев 2015

  • Автор темы
  • #3

Добавляете такую опцию curl_setopt( $ch, CURLOPT_HEADER, 1 ). В результате curl будет выдавать ответ с заголовками.

PHP:

$ch = curl_init();
curl_setopt( $ch, CURLOPT_HEADER, 1 );
$curlResult = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close ($ch );

if ($code == 502 || $code == 503){
echo 'Выпал код 502 или 503'
}

Из заголовков можно выпить ответ сервера.
Далее , если выпал нужный код ошибки, просто повторно делается запрос на получение страницы или таймаут и запрос.

А можно поподробнее?
Просто нужно спарсить несколько статей с сайта, а там cloudflare защита от ДДОС стоит, и заглушка выдает ошибку 503 для курла.

Последнее редактирование: 19 Фев 2015

  • #4

cloudflare не получится полностью автоматически обойти используя cURL,
там некоторые заголовки устанавливаются «на лету» с помощью JavaScript,
который cURL обрабатывать не умеет.

советую посмотреть в сторону Для просмотра ссылки Войди или Зарегистрируйся или Для просмотра ссылки Войди или Зарегистрируйся

  • Автор темы
  • #5

cloudflare не получится полностью автоматически обойти используя cURL,
там некоторые заголовки устанавливаются «на лету» с помощью JavaScript,
который cURL обрабатывать не умеет.

советую посмотреть в сторону Для просмотра ссылки Войди или Зарегистрируйся или Для просмотра ссылки Войди или Зарегистрируйся

Насколько я читал, там выдается какое-то автоматически сгенерированное выражение, которое браузер должен посчитать и выдать ответ, или я неправ?

Как понял браузер должен расчитать математическое выражение из javascript и передать его в форму, если верно то получишь куку
А как это в курл реализовать?
К примеру идет запрос на курле, если попадается ошибка 502 или 503 использовать selenuim

if ($info[‘http_code’]== 502 || $info[‘http_code’] == 503){

тут запускает обход, как его реализовать?

}

Последнее редактирование: 19 Фев 2015

  • #6

Насколько я читал, там выдается какое-то автоматически сгенерированное выражение, которое браузер должен посчитать и выдать ответ, или я неправ?
Как понял браузер должен расчитать математическое выражение из javascript и передать его в форму, если верно то получишь куку
А как это в курл реализовать?

там несколько видов защиты, математический challenge самый простой.
попробуй на него натравить этот скрипт:

Код:

function request($url, $post = array()) {
    $headers[] = 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0';
    $headers[] = 'Accept: application/json, text/javascript, */*; q=0.01';
    $headers[] = 'Accept-Language: ru,en;q=0.5';
    $headers[] = 'Connection: keep-alive';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    if(count($post) > 0) {
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    }
    curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
    curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
    $data = curl_exec($ch);
    return $data;
}

$url = 'http://.....';

$data = request($url);
preg_match('/<form id="ChallengeForm" .+ name="act" value="(.+)".+name="jschl_vc" value="(.+)".+</form>.+jschl_answer.+(([0-9+-*]+));/Uis', $data, $out);
if(count($out) > 0) {
    eval("$jschl_answer=$out[3];");
    $post['act'] = $out[1];
    $post['jschl_vc'] = $out[2];
    $post['jschl_answer'] = $jschl_answer;
    sleep(5);
    $data = request($url, $post);
}
var_dump($data);

  • Автор темы
  • #7

Вроде то, что нужно, показывает страницу защиты, затем редиректит, только почему то не на $url редиректит
а Обратно на test1.ru
т.е. получаю к примеру Для просмотра ссылки Войди или Зарегистрируйся
а не Для просмотра ссылки Войди или Зарегистрируйся

Как дописать?

  • Автор темы
  • #8

Like @netlander the workaround of bypassing the Apache proxy worked for me. It was crashing at that step: «POST git-receive-pack (7200216 bytes)», but this works normally without the proxy.

Might well be related to the 401: with the Apache mod_proxy, I did not receive an authentication request, but I received one without the proxy and had to type user/password for the commit to be accepted.

Apache error log (multiple identical lines):

[Sat Jan 12 09:12:33.710124 2019] [proxy:error] [pid 25787] (32)Broken pipe: [client 37.58.212.212:59962] AH01084: pass request body failed to 127.0.0.1:3000 (127.0.0.1)
[Sat Jan 12 09:12:33.710162 2019] [proxy_http:error] [pid 25787] [client 37.58.212.212:59962] AH01097: pass request body failed to 127.0.0.1:3000 (127.0.0.1) from 37.58.212.212 ()

Gogs log/hooks/post-receive.log (9:20 is without the proxy, nothing visible at 9:12 with the proxy):

2019/01/12 09:20:41 [ERROR] [...ogs/models/action.go:493 CommitRepoAction()] UpdateIssuesCommit: invalid issue reference [ref: 09/01/2019]

Other log/hooks/* files are touched but empty

Portion of the log/gogs.log which appears relevant, without the proxy:

2019/01/12 09:20:41 [TRACE] HTTPGit - Authenticated user: fgm
2019/01/12 09:20:41 [TRACE] Session ID: d8376360d674a0ea
2019/01/12 09:20:41 [TRACE] CSRF Token: FKyzeZELo1j4eoGE-TKp3yDmyc06MTU0NzI4NDg0MTU0MjMxMjM2MA==
2019/01/12 09:20:41 [TRACE] Detected encoding: UTF-8 (fast)
2019/01/12 09:20:41 [TRACE] Template: repo/home
2019/01/12 09:20:41 [TRACE] Session ID: 9e0fc1184eb4970b
2019/01/12 09:20:41 [TRACE] CSRF Token: M0fhCH0kbQAhgfPKdmaXSga1DPk6MTU0NzI4NDg0MTkxMjIwMDAwOA==
2019/01/12 09:20:41 [TRACE] TriggerTask 'assets__prague2013_blocks/blocks-1-8' by 'fgm'
2019/01/12 09:20:41 [TRACE] DeliverHooks [repo_id: 112]
2019/01/12 09:20:41 [TRACE] AddTestPullRequestTask [head_repo_id: 112, head_branch: blocks-1-8]: finding pull requests
2019/01/12 09:20:41 [TRACE] AddTestPullRequestTask [base_repo_id: 112, base_branch: blocks-1-8]: finding pull requests

More interestingly, updating my HTTPS Vhost to look like this, as suggested on https://httpd.apache.org/docs/2.4/en/mod/mod_proxy.html#envsettings , fixed the issue for me. It causes the browser to ask for credentials (triggering keychain access in macOS), and succeeds:

  ProxyPreserveHost On
  ProxyRequests off
  ProxyPass / http://127.0.0.1:3000/
  ProxyPassReverse / http://127.0.0.1:3000/
  SetEnv force-proxy-request-1.0 1
  SetEnv proxy-nokeepalive 1

This might suggest a problem with HTTP/1.1 keepalive handling in Gogs or its dependencies.

Понравилась статья? Поделить с друзьями:
  • Curl игнорировать ssl ошибку php
  • Curl php получить ошибку
  • Curl error 6 could not resolve host ошибка
  • Curl 301 ошибка
  • Cureit ошибка удаления