Git-Raw

 view release on metacpan or  search on metacpan

deps/libgit2/src/libgit2/transports/http.c  view on Meta::CPAN

	int error;

	/* NTLM requires a full challenge/response */
	if (transport->server.auth_schemetypes == GIT_HTTP_AUTH_NTLM)
		steps = GIT_AUTH_STEPS_NTLM;

	/*
	 * Send at most two requests: one without any authentication to see
	 * if we get prompted to authenticate.  If we do, send a second one
	 * with the first authentication message.  The final authentication
	 * message with the response will occur with the *actual* POST data.
	 */
	for (step = 0; step < steps && !complete; step++) {
		git_net_url_dispose(&url);
		git_http_response_dispose(&response);

		if ((error = generate_request(&url, &request, stream, len)) < 0 ||
		    (error = git_http_client_send_request(client, &request)) < 0 ||
		    (error = git_http_client_send_body(client, probe, len)) < 0 ||
		    (error = git_http_client_read_response(&response, client)) < 0 ||
		    (error = git_http_client_skip_body(client)) < 0 ||
		    (error = handle_response(&complete, stream, &response, true)) < 0)
			goto done;
	}

done:
	git_http_response_dispose(&response);
	git_net_url_dispose(&url);
	return error;
}

/*
* Write to an HTTP transport - for the first invocation of this function
* (ie, when stream->state == HTTP_STATE_NONE), we'll send a POST request
* to the remote host.  If we're sending chunked data, then subsequent calls
* will write the additional data given in the buffer.  If we're not chunking,
* then the caller should have given us all the data in the original call.
* The caller should call http_stream_read_response to get the result.
*/
static int http_stream_write(
	git_smart_subtransport_stream *s,
	const char *buffer,
	size_t len)
{
	http_stream *stream = GIT_CONTAINER_OF(s, http_stream, parent);
	http_subtransport *transport = OWNING_SUBTRANSPORT(stream);
	git_net_url url = GIT_NET_URL_INIT;
	git_http_request request = {0};
	git_http_response response = {0};
	int error;

	while (stream->state == HTTP_STATE_NONE &&
	       stream->replay_count < GIT_HTTP_REPLAY_MAX) {

		git_net_url_dispose(&url);
		git_http_response_dispose(&response);

		/*
		 * If we're authenticating with a connection-based mechanism
		 * (NTLM, Kerberos), send a "probe" packet.  Servers SHOULD
		 * authenticate an entire keep-alive connection, so ideally
		 * we should not need to authenticate but some servers do
		 * not support this.  By sending a probe packet, we'll be
		 * able to follow up with a second POST using the actual
		 * data (and, in the degenerate case, the authentication
		 * header as well).
		 */
		if (needs_probe(stream) && (error = send_probe(stream)) < 0)
			goto done;

		/* Send the regular POST request. */
		if ((error = generate_request(&url, &request, stream, len)) < 0 ||
		    (error = git_http_client_send_request(
			transport->http_client, &request)) < 0)
			goto done;

		if (request.expect_continue &&
		    git_http_client_has_response(transport->http_client)) {
			bool complete;

			/*
			 * If we got a response to an expect/continue, then
			 * it's something other than a 100 and we should
			 * deal with the response somehow.
			 */
			if ((error = git_http_client_read_response(&response, transport->http_client)) < 0 ||
			    (error = handle_response(&complete, stream, &response, true)) < 0)
			    goto done;
		} else {
			stream->state = HTTP_STATE_SENDING_REQUEST;
		}

		stream->replay_count++;
	}

	if (stream->state == HTTP_STATE_NONE) {
		git_error_set(GIT_ERROR_HTTP,
		              "too many redirects or authentication replays");
		error = GIT_ERROR; /* not GIT_EAUTH because the exact cause is unclear */
		goto done;
	}

	GIT_ASSERT(stream->state == HTTP_STATE_SENDING_REQUEST);

	error = git_http_client_send_body(transport->http_client, buffer, len);

done:
	git_http_response_dispose(&response);
	git_net_url_dispose(&url);
	return error;
}

/*
* Read from an HTTP transport after it has been written to.  This is the
* response from a POST request made by http_stream_write.
*/
static int http_stream_read_response(
	git_smart_subtransport_stream *s,
	char *buffer,
	size_t buffer_size,
	size_t *out_len)



( run in 0.840 second using v1.01-cache-2.11-cpan-39bf76dae61 )