Page MenuHomePhabricator

Arcanist 404 when installing certificate
Closed, ResolvedPublic

Asked by gracicot on Aug 26 2016, 12:12 PM.
Tags
None
Referenced Files
None
Tokens
"Burninate" token, awarded by michaeljs1990.

Details

I recently tried to configure arcanist on my machine. When I tried to connect it to my phabricator server, I got this error:

$ arc install-certificate

CONNECT  Connecting to "http://my.phabserver.com:8080/api/"...
Usage Exception: Failed to connect to server (http://my.phabserver.com:8080/api/): [HTTP/404] Not Found
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>404 - Not Found</title>
 </head>
 <body>
  <h1>404 - Not Found</h1>
 </body>
</html>

However, when I go to http://my.phabserver.com:8080/ on my web browser, everything seems fine.
Did I missed something in my phabricator installation?

EDIT: Added the port, since it can be valuable information.

This is my host section of my lighttpd.conf file:

$HTTP["host"] =~ "my.phabserver.com:8080" {
  server.document-root = "/srv/http/phabricator/webroot"
  url.rewrite-once = (
    "^(/rsrc/.*)$" => "$1",
    "^(/favicon.ico)$" => "$1",
    # This simulates QSA (query string append) mode in Apache
    "^(/[^?]*)\?(.*)" => "/index.php?__path__=$1&$2",
    "^(/.*)$" => "/index.php?__path__=$1",
  )
}

Answers

michaeljs1990
Updated 2,798 Days Ago

This was bothering me. I dug into the conduit api and found this.

HTTPSFuture.php

// cURL sends an "Expect" header by default for certain requests. While
// there is some reasoning behind this, it causes a practical problem
// in that lighttpd servers reject these requests with a 417. Both sides
// are locked in an eternal struggle (lighttpd has introduced a
// 'server.reject-expect-100-with-417' option to deal with this case).
//
// The ostensibly correct way to suppress this behavior on the cURL side
// is to add an empty "Expect:" header. If we haven't seen some other
// explicit "Expect:" header, do so.
//
// See here, for example, although this issue is fairly widespread:
//   http://curl.haxx.se/mail/archive-2009-07/0008.html

if you comment out this line $headers[] = 'Expect:'; in HTTPSFuture.php arc will work for you however it looks like you need to configure lighttpd properly for use with phabricator.

A small side note on security. You leaked your public IP in the logs above and have a webserver serving all files including your config.json.

@epriestley this one is a bit strange to me and i'm not sure I completely understand the comment correctly. It seems that curl historically adds Expect 100 so this is turning it off. However new versions of lighttpd return 404 when this header is included. However I haven't been able to find any reports of this specific 404 error. In this case it seems completely removing the expect header is the fix but I'm not sure if that will cause issues elsewhere.

Steps to reproduce

  1. Obtain a fresh copy of ubuntu server 14.04 / 16.06 will likely work exactly the same outside of going through a different install process for php5.
  2. sudo apt-get install lighttpd git php5 php5-cgi php5-fpm php5-mysql
  3. mkdir /srv/httpd & cd /srv/httpd
  4. clone arc, libphutil, phab into this directory
  5. modify /etc/lighttpd/lighttpd.conf with the output provided
  6. service lighttpd restart && service lighttpd force-reload
  7. add lightphab.dev to the /etc/hosts file of the computer you want to run arc from.
# lighttpd.conf file

server.modules = (
	"mod_access",
	"mod_alias",
	"mod_compress",
 	"mod_redirect",
        "mod_rewrite",
)

server.document-root        = "/srv/httpd"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 8080


index-file.names            = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

# default listening port for IPv6 falls back to the IPv4 port
## Use ipv6 if available
#include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

$HTTP["host"] =~ "lightphab.dev:8080" {
  server.document-root = "/srv/httpd/phabricator/webroot"
  url.rewrite-once = (
    "^(/rsrc/.*)$" => "$1",
    "^(/favicon.ico)$" => "$1",
    # This simulates QSA (query string append) mode in Apache
    "^(/[^?]*)\?(.*)" => "/index.php?__path__=$1&$2",
    "^(/.*)$" => "/index.php?__path__=$1",
  )
}

Now you can try to install a cert from this server that is reachable from the browser which will give you the following.

arc install-cert http://lightphab.dev:8080
 CONNECT  Connecting to "http://lightphab.dev:8080/api/"...
Usage Exception: Failed to connect to server (http://lightphab.dev:8080/api/): [HTTP/404] Not Found
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>404 - Not Found</title>
 </head>
 <body>
  <h1>404 - Not Found</h1>
 </body>
</html>

You can now edit one line in HTTPSFuture.php which should be 282 $headers[] = 'Expect:'; just comment it out.

and the above is wrong...... I am finding out as I try to type up the rest of this... I'll be posting a diff in a second to fix this issue.

gracicot
Updated 2,798 Days Ago

I FINALLY FIXED IT!! But be aware that it's a huge patch and I suspect a bug in libphutil.

I changed my host configuration of lighttpd from

$HTTP["host"] =~ "my.phabserver.com:8080" {
  server.document-root = "/srv/http/phabricator/webroot"
  url.rewrite-once = (
    "^(/rsrc/.*)$" => "$1",
    "^(/favicon.ico)$" => "$1",
    # This simulates QSA (query string append) mode in Apache
    "^(/[^?]*)\?(.*)" => "/index.php?__path__=$1&$2",
    "^(/.*)$" => "/index.php?__path__=$1",
  )
}

To

# You can use the regex or just put 'my.phabserver.com'
$HTTP["host"] =~ "(^|\.)my\.phabserver\.com(\:[0-9]*)?$" {
  server.document-root = "/srv/http/phabricator/webroot"
  url.rewrite-once = (
    "^(/rsrc/.*)$" => "$1",
    "^(/favicon.ico)$" => "$1",
    # This simulates QSA (query string append) mode in Apache
    "^(/[^?]*)\?(.*)" => "/index.php?__path__=$1&$2",
    "^(/.*)$" => "/index.php?__path__=$1",
  )
}

Now both the web and arcanist are working great.
Morale of this story: Don't add the port in the host regex of lighttpd, or arcanist won't work.

Thanks for all your support! I would not have found all this without all of you!
I wonder if this worth a bug report? Seems I found quite of a corner case. Maybe add a warning in the documentation for the moment?

EDIT: For those new here, here's how I found the origin of this error.
This is the log for the command curl -v -XPOST -d'params=[]&output=json&__conduit__=1' "http://my.phabserver.com:8080/api/conduit.ping":

2016-08-27 12:22:22: (request.c.436) fd: 6 request-len: 170 \nPOST /api/conduit.ping HTTP/1.1\r\nHost: my.phabserver.com:8080\r\nUser-Agent: curl/7.50.1\r\nAccept: */*\r\nContent-Length: 35\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n

This is the log for arc install-certificate 'http://my.phabserver.com:8080/api/':

2016-08-27 12:22:43: (request.c.436) fd: 6 request-len: 140 \nPOST /api/conduit.ping HTTP/1.1\r\nHost: my.phabserver.com\r\nAccept: */*\r\nContent-Length: 39\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n

As you can see, the host section is different between the two: one has the port 8080 and work, and the other has not the port and fail.

New Answer

Answer

This question has been marked as closed, but you can still leave a new answer.