Evert PotDiscovering features using HTTP OPTIONS (16.10.2024, 13:44 UTC)

Say you have an API, and you want to communicate what sort of things a user can do on a specific endpoint. You can use external description formats like OpenAPI or JSON Schema, but sometimes it’s nice to also dynamically communicate this on the API itself.

OPTIONS is the method used for that. You may know this HTTP method from CORS, but it’s general purpose is for clients to passively find out ‘What can I do here?’.

All HTTP clients typically support making OPTIONS request. For example with fetch():

const response = await fetch(
  'https://example.org',
  {method: 'OPTIONS'}
);

A basic OPTIONS response might might look like this:

HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 02:57:38 GMT
Server: KKachel/1.2
Allow: GET, PUT, POST, DELETE, OPTIONS

Based on the Allow header you can quickly tell which HTTP methods are available at a given endpoint. Many web frameworks emit this automatically and generate the list of methods dynamically per route, so chances are that you get this one for free.

To find out if your server does, try running the command below (with your URL!):

curl -X OPTIONS http://localhost:3000/some/endpoint/

One nice thing you could do with the Allow header, is that you could also communicate access-control information on a very basic level. For example, you could only include DELETE and PUT if a user has write access to a resource.

Accept and Accept-Encoding

There’s server other standard headers for discovery. Here’s an example showing a few at once:

HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 02:57:38 GMT
Server: KKachel/1.2
Allow: GET, PUT, POST, DELETE, OPTIONS
Accept: application/vnd.my-company-api+json, application/json, text/html
Accept-Encoding: gzip,brotli,identity

You may already be familiar with Accept and Accept-Encoding from HTTP requests, but they can also appear in responses. Accept in a response lets you tell the client which kind of mimetypes are available at an endpoint. I like adding text/html to every JSON api endpoint and making sure that API urls

Truncated by Planet PHP, read more at the original (another 11304 bytes)

Link
PHP: Hypertext PreprocessorPHP 8.4.0 RC2 available for testing (10.10.2024, 00:00 UTC)
The PHP team is pleased to announce the release of PHP 8.4.0, RC2. This is the second release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the PHP Wiki. For source downloads of PHP 8.4.0, RC2 please visit the download page. Please carefully test this version and report any issues found in the bug reporting system. Please DO NOT use this version in production, it is an early test version. For more information on the new features and other changes, you can read the NEWS file or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release will be RC 3, planned for 24 October 2024. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
Link
Brian MoonVarnish Workspace Error (7.10.2024, 17:21 UTC)

We had been having an issue with losing cookies in Varnish. Because of how Varnish works, the way to work around cookies is to store them in headers inbetween states of the request process. We were finally able to get some data out of varnishlog that looked like this.

      - ReqHeader DN-Varnish-Offer-Group: 
- LostHeader DN-Varnish-Offer-Sort: price
- Error out of workspace (req)
- LostHeader DN-Varnish-Sbtab-Sorts:
- Error out of workspace (req)
- LostHeader DN-Varnish-Use-View:
- Error out of workspace (req)
- LostHeader DN-Varnish-Ux-Variant: classic_site
- Error out of workspace (req)

When you first read these errors, you will likely find the settings workspace_client and workspace_backend. Those seem like very logical settings to tweak. However, no matter how big we set them nothing helped. We graph stats coming out of Varnish using the prometheus exporter. We found the metric varnish_main_ws_backend_overflow. That made us believe even more that this was a workspace_backend limit we were hitting. It turns out, there is more to the workspace settings than just this. I read through an old issue on Github and found some folks trying to set other settings related to header size and header limits. In the end, that was our issue. We increased these settings and our overflows disappeared. 

http_req_hdr_len = 64k (default is 8k)
http_req_size = 128k (default is 32k)
http_max_hdr=256 (default is 64)

Hopefully this will help someone else that runs up against this.

Link
Evert PotNew Structured Fields RFC out, and so is my Javascript package (3.10.2024, 15:56 UTC)

A new RFC was released for Structured Fields: RFC9651.

What is it?

HTTP headers have been a bit of a free-for all in terms of how complex values are encoded, with many headers requiring their own mini-parser.

A while back an effort was started to fix this for headers going forward, named ‘Structured Fields’. They’re called Fields and not ‘Headers’ because HTTP has both Headers and Trailers!

Structured fields let you encode things like lists, dictionaries, strings, numbers, booleans and binary data. The original RFC from 2021 is pretty successful and although many existing headers can’t be retrofitted to this format, a lot of new standards are taking advantage.

Some examples:

# Parsed an ASCII string
Header: "foo"

# A simple string, called a 'Token' in the spec
Header: foo

# Parsed as number
Header: 5
Header: -10
Header: 5.01415

# Parsed into boolean
Header: ?1
Header: ?0

# Binaries are base64 encoded
Header: :RE0gbWUgZm9yIGEgZnJlZSBjb29raWU=:

# Items can have parameters
Header: "Hello world"; a="5"

# A simple list
Header: 5, "foo", bar, ?1

# Each element can have parameters
Header: sometoken; param1; param2=hi, 42

# A list can also contain lists itself. These are called 'inner lists' and
# use parenthesis
Header: sometoken, (innerlistitem1 innerlistitem2), (anotherlist)

# A simple dictionary
Header: fn="evert", ln="pot", coffee=?1

# Each item may have parameters too
Header: foo=123; q=1, bar=123, q=0.5

# A dictionary value may be an inner list again
Header: foo=(1 2 3)

The new RFC published last week adds 2 new data types: Dates and ‘Display strings’, which is a Unicode serialization that fits in the HTTP header (and trailer) format.

# Parsed into a Date object
Header: @1686634251

# A Unicode string, called a 'Display String' in the spec. They use
# percent encoding, but encode a different set of characters than
# URLs.
Header %"Frysl%C3%A2n"

Why should you care?

If you encounter these headers in the wild, it’s a really good idea to use a standard parser. One of the reasons is that with using structured-fields, there’s a built-in extension mechanism. You’ll want to make sure that when a new parameter appears your application doesn’t suddenly break.

You may also want to define and use your own HTTP headers. The structured fields format is a very good ‘default choice’ that removes decisions such as ‘How should I encode a key value object’ or ‘how do I encode a UTF-8 string’.

With parsers popping up for every language, you don’t have to worry about writing your own one-off formats.

Javascript package

I’m the maintainer of a Javascript library for Structured Fields, called “structured headers”, which I’ve also updated for this new RFC. I wish I picked the name “structured-fields”, but I picked the name before the original standard changed it’s name.

I’ve just released v2 of this library supporting these new types, and also added ES Modules support.

Comments?

Reply to one of these:

Link
Evert PotHello World, meet Kian (2.10.2024, 15:08 UTC)

One week ago on September 24th my son Kian was born, after a 5 year fertility journey with my wife Roxy. Roxy and Kian are well and I’m really excited for everything that comes next!

Link
PHP: Hypertext PreprocessorPHP 8.4.0 RC 1 now available for testing (26.9.2024, 00:00 UTC)
The PHP team is pleased to announce the release of PHP 8.4.0, RC 1. This is the first release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the PHP Wiki. For source downloads of PHP 8.4.0, RC 1 please visit the download page. Please carefully test this version and report any issues found in the bug reporting system. Please DO NOT use this version in production, it is an early test version. For more information on the new features and other changes, you can read the NEWS file or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. The next release will be RC 2, planned for 10 October 2024. The signatures for the release can be found in the manifest or on the QA site. Thank you for helping us make PHP better.
Link
Rob AllenIncrease truncated body in a Guzzle exception (24.9.2024, 10:00 UTC)

When Guzzle throws BadResponseException, the message includes information about the method, URL response code and then a truncated part of the body.

For example:

"Client error: `GET https://dev.clientproject.com:4444/oauth2/authorize?client_id=983e98d2fab8756a&scope=scope&response_type=code&redirect_uri=%2Fhome&code_challenge=some_code_challenge_here` resulted in a `400 Bad Request` response:
{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parame (truncated...)

To retrieve the full text of the body, you grab it from the response property of the exception:

$body = $e->getResponse()->getBody()->getContents();

Changing the truncation limit

If you want more text in the exception message you need to pass a handler stack to the Client's constructor with an httpErrors middleware that has a BodySummarizer with a larger truncation limit.

The easiest way to do this is to create the default stack and then modify it:

use GuzzleHttp\BodySummarizer;
use GuzzleHttp\HandlerStack;

// ...

$stack = HandlerStack::create();
$stack->remove('http_errors');
$stack->unshift(Middleware::httpErrors(new BodySummarizer(1500)), 'http_errors');

Set the number of characters to truncate at in the BodySummarizer's constructor. I picked 1500; the default is 120 (as of this time of writing).

After creating the stack, we remove the current httpErrors middleware and add a new one. Note that it needs to be first in the stack as we want it to handle any error from any subsequent middleware too.

We then create our client with our custom stack:

use GuzzleHttp\Client;

// ...

$this->client = new Client([
    'handler'  => $stack,
    'base_uri' => $this->baseUri,
]);

That's it. There's now more text in the BadResponseException message.

Link
Doug HillMenciptakan Nuansa Mewah dengan Jasa Desain Interior Bandung (19.9.2024, 15:24 UTC)

Setiap orang tentu ingin memiliki hunian yang nyaman dan indah. Namun, menciptakan nuansa mewah di rumah Anda membutuhkan perencanaan yang matang. Banyak faktor yang perlu dipertimbangkan, mulai dari pemilihan material hingga pengaturan pencahayaan.

Di sinilah peran jasa desain interior menjadi sangat penting, jasa profesional tidak hanya membantu Anda mewujudkan impian, tetapi juga memastikan setiap detail terlihat mewah dan harmonis. Mari kita bahas lebih dalam bagaimana jasa desain interior Bandung bisa menciptakan nuansa mewah di hunian Anda.

Cara Jasa Desain Interior Menciptakan Nuansa Mewah

1. Pemilihan Material Berkualitas

Material berkualitas tinggi adalah salah satu kunci utama menciptakan nuansa mewah. Desainer interior akan membantu Anda memilih material yang tahan lama dan elegan, seperti marmer, kayu solid, atau logam berlapis. Bahan-bahan ini tidak hanya meningkatkan tampilan, tetapi juga daya tahan furnitur dan elemen dekoratif di rumah Anda.

Selain itu, pemilihan material juga harus memperhatikan kesesuaian dengan konsep desain. Material yang tepat akan memberikan kesan eksklusif dan elegan tanpa mengabaikan fungsi. Dengan bantuan jasa desain interior, Anda dapat memastikan pilihan material yang sesuai dengan visi dan anggaran Anda.

2. Penataan Pencahayaan yang Tepat

Pencahayaan memainkan peran penting dalam menciptakan suasana mewah. Desainer interior profesional akan membantu Anda merancang sistem pencahayaan yang tidak hanya fungsional, tetapi juga estetis. Pencahayaan yang tepat bisa memperkuat kesan ruangan yang lebih luas dan lebih nyaman.

Pemanfaatan lampu gantung, lampu dinding, atau bahkan pencahayaan tersembunyi bisa membuat perbedaan besar. Jasa desain interior Bandung memastikan bahwa setiap sudut ruangan mendapatkan pencahayaan yang ideal untuk menonjolkan kemewahan desainnya.

3. Kombinasi Warna yang Harmonis

Warna memegang peran penting dalam menciptakan suasana mewah. Desainer interior tahu bagaimana mengombinasikan warna-warna netral seperti putih, krem, dan abu-abu dengan sentuhan warna yang lebih tegas. Kombinasi warna ini akan menghasilkan kesan elegan yang tetap hangat.

Pilihan warna yang tepat juga membantu memberikan dimensi pada ruangan Anda. Dengan menggunakan jasa desain interior, Anda akan mendapatkan panduan dalam memilih palet warna yang tidak hanya cantik, tetapi juga memancarkan kemewahan.

4. Pemanfaatan Ruang Secara Optimal

Salah satu keahlian desainer interior adalah memaksimalkan ruang yang ada. Mereka akan merancang tata letak yang tidak hanya fungsional tetapi juga estetik. Setiap ruang akan dimanfaatkan dengan baik, sehingga tidak ada sudut yang terbuang.

Dengan jasa desain interior, Anda dapat menciptakan ruang yang terorganisir, rapi, dan mewah. Desainer akan memastikan setiap elemen dekoratif dan furnitur ditempatkan pada posisi yang tepat untuk memaksimalkan keindahan dan kenyamanan ruangan Anda.

5. Penempatan Aksen Dekoratif yang Menawan

Aksen dekoratif seperti lukisan, patung, atau hiasan dinding adalah elemen yang tidak boleh diabaikan. Desainer interior akan membantu Anda memilih aksen yang sesuai dengan tema mewah yang ingin Anda hadirkan. Aksen ini bisa menjadi pusat perhatian yang menarik di ruangan Anda.

Aksen dekoratif yang dipilih dengan cermat akan memberikan karakter unik pada ruangan Anda. Dengan jasa desain interior, setiap aksen akan dipadukan secara harmonis untuk menciptakan kesan yang lebih eksklusif.

6. Pilihan Furnitur yang Elegan

Furnitur adalah elemen kunci dalam desain interior. Jasa desain interior membantu Anda memilih furnitur yang tidak hanya nyaman tetapi juga elegan. Penggunaan furnitur dengan desain yang unik dan berkualitas tinggi akan menambah kesan mewah pada hunian Anda.

Pemilihan furnitur juga harus sesuai dengan tema dan gaya desain yang diinginkan. Desainer interior akan membantu Anda menemukan furnitur yang mampu memadukan kenyamanan, fungsi, dan estetika dengan sempurna.

Mewujudkan Hunian Mewah dengan Sentuhan Profesional

Jika Anda ingin menciptakan hunian mewah dengan nuansa yang elegan, bantuan jasa desain interior profesional adalah pilihan yang tepat. Mereka tidak hanya membantu Anda dalam merancang konsep, tetapi juga merealisasikan visi Anda menjadi kenyataan. Setiap detail diperhatikan agar sesuai dengan keinginan dan anggaran Anda.

Dengan bekerja sama dengan jasa desain interior Bandung, Anda bisa mendapatkan hunian yang mencerminkan kemewahan dan kenyamanan. Dari pemilihan material hingga penataan ruang, desainer interior akan memastikan hasil akhir yang memuaskan.

Jika Anda tertarik u

Truncated by Planet PHP, read more at the original (another 546 bytes)

Link
Rob AllenFixing PhpStorm cannot find a local copy of Standard Input Code (17.9.2024, 10:00 UTC)

Recently, I set up my PHP dev environment to allow me to step debug from unit tests that I run with make unit

The relevant parts of Makefile look like this:

# Set DEBUG=1 to enable Xdebug
ifeq ($(origin DEBUG),undefined)
    XDEBUG :=
else
    XDEBUG := XDEBUG_SESSION=PHPSTORM
endif


unit: ## Run unit tests
        docker compose exec php bash -c "$(XDEBUG) vendor/bin/phpunit --testsuite=unit"

I can now set a break point and run the unit tests with Xdebug enabled with DEBUG=1 make unit.

I have an environment variable set in compose.yaml: PHP_IDE_CONFIG=serverName=project.com.localhost and I use to set up the mappings in PhpStorm's settings. As we're using Docker, I also have xdebug.client_host = host.docker.internal set up in my PHP ini settings.

I noticed that when I didn't have a breakpoint set, PhpStorm would break with this error in Debug console for a particular test:

Screen shot of PhpStorm with the words

That's a strange error message: "Cannot find a local copy of the file on server /var/www/html/Standard input code"! Clearly I don't have a file called "Standard input code" and so it's not surprising that PhpStorm can't map to it.

Google to the rescue!

I eventually worked out that it's related to having a test with the @runInSeparateProcess annotation. As a result, phpunit does some magic and Xdebug sends through a file that it has labeled as "Standard input code" – presumably as it was injected via stdin..

To fix this, I disabled these PhpStorm settings in PHP -> Debug:

  • "Break at first line in PHP scripts" in the External connections section
  • "Force break at first line when no path mapping specified" in the Xdebug section

In PhpStorm 2024, it looks like this:

2024 08 20 phpstorm settings.

Of course, you'll have to manually set up path mappings in PHP -> Servers, but I do that anyway, so not really a problem for me, at least.

Problem solved!

Link
Christopher JonesPipelined database operation performance redux with python-oracledb: very impressive (12.9.2024, 07:27 UTC)

In Pipelined database operations with python-oracledb 2.4 I gave a simple benchmark showing the performance benefit of Oracle Database 23ai Pipelining. We now have results which are even more impressive.

Photo by Matt Paul Catalano on Unsplash

The system testing team (thank you!) ran a performance evaluation with Python 3.12 and python-oracledb 2.4.1 using the same schema they had used for their ODP.NET Pipelining benchmark (discussed here).

The app used 100 threads that repeatedly executed different SELECT statements. The tests measured performance metrics over 20,000 iterations with pipelining enabled versus pipelining disabled:

  • Pipelining runs finished 530% faster on average.
  • Pipelining runs performed 529% more transactions per second.
  • Pipelining runs performed 52% more transactions per second per processor.

I’m not sure I think that last stat is what it says it is, or that it is useful, but I include it for completeness with the ODP.NET results. Regardless the time and TPS figures are very significant!

One interesting, but obvious when you think about it, note is that client CPU usage increases with Pipelining because the client is able to be kept busy and do more work.

Resources


Pipelined database operation performance redux with python-oracledb: very impressive was originally published in Oracle Developers on Medium, where people are continuing the conversation by highlighting and responding to this story.

Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP